Export (0) Print
Expand All

ThreadHelper.Invoke Method (Action)

Calls an action on the UI thread, re-entering (if necessary) any code already executing on the UI thread.

Namespace:  Microsoft.VisualStudio.Shell
Assembly:  Microsoft.VisualStudio.Shell.12.0 (in Microsoft.VisualStudio.Shell.12.0.dll)

'Declaration
Public Sub Invoke ( _
	action As Action _
)

Parameters

action
Type: System.Action

The action to perform.

If the caller is already on the UI thread, then the call is made directly. Otherwise, the call is transferred onto the UI thread, and this thread blocks until the call returns. If the UI thread throws an exception, that exception is transferred and thrown again on this thread.

This method uses an RPC message to marshal to the UI thread. This will allow the marshaled delegate to execute on the UI thread while the UI thread is already busy executing a previous message. This tends to introduce reentrancy, hangs and crashes, and therefore should be avoided if possible.

A far safer approach, which protects the stability of the process, is to use BeginInvoke, which only enters the UI thread when it is not otherwise busy. If you wish to synchronously block your background thread until the delegate has completed execution on the UI thread, you can use a helper method such as:

Private static T UiInvoke<T>(Func<T> function)
{
// If we’re already on the UI thread, just execute the method directly.
if (CheckAccess()){return function();}
T result = default(T);
// Prefer BeginInvoke over Invoke since BeginInvoke is potentially saver than Invoke.
using(ManualResetEventSlim eventHandle = new ManualResetEventSlim(false))
{
ThreadHelper.Generic.BeginInvoke(() =>{result = function();eventHandle.Set();});
// Wait for the invoke to complete.
var success = eventHandle.Wait(TimeSpan.FromSeconds(UiInvokeTimeoutSeconds));
// If the operation timed out, fail.
if (!success){throw new TimeoutException();
}

return result; }

Show:
© 2014 Microsoft