, - , .NET 2.0. . Control.Invoke . WinFormsSynchronizationContext, WinForms, Control.BeginInvoke Post Control.Invoke Send.
? , "synced/invoked" ?
"" "". Control.Invoke - , :
int Test()
{
throw new InvalidOperationException("Surpise from the UI thread!");
}
void Form_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(x =>
{
try
{
this.Invoke((MethodInvoker)Test);
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
});
}
SynchronizationContext WinForms. , WinForms, WPF, Windows Phone, Xamarin :
var uiSynchronizationContext = System.Threading.SynchronizationContext.Current;
if (uiSynchronizationContext == null)
throw new NullReferenceException("SynchronizationContext.Current");
ThreadPool.QueueUserWorkItem(x =>
{
try
{
uiSynchronizationContext.Send(s => Test(), null);
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
}
});
, Control.Invoke ( SynchronizationContext.Send) . Control.BeginInvoke ( SynchronizationContext.Post), . , Control.BeginInvoke , , , Application.Run.
, , . # 5.0 Task.ContinueWith.
:
class ErrorEventArgs : EventArgs
{
public Exception Exception { get; set; }
}
event EventHandler<ErrorEventArgs> Error = delegate { };
void Form_Load(object sender, EventArgs e)
{
this.Error += (sError, eError) =>
Debug.Print(eError.Exception.ToString());
ThreadPool.QueueUserWorkItem(x =>
{
this.BeginInvoke(new MethodInvoker(() =>
{
try
{
Test();
}
catch (Exception ex)
{
this.Error(this, new ErrorEventArgs { Exception = ex });
}
}));
});
}
ContinueWith:
ThreadPool.QueueUserWorkItem(x =>
{
var tcs = new TaskCompletionSource<int>();
uiSynchronizationContext.Post(s =>
{
try
{
tcs.SetResult(Test());
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}, null);
tcs.Task.ContinueWith(task =>
{
Debug.Print(task.Exception.ToString());
}, TaskContinuationOptions.OnlyOnFaulted);
});
, # 5.0, async/await , , try/catch, :
int Test()
{
throw new InvalidOperationException("Surpise from the UI thread!");
}
async void Form_Load(object sender, EventArgs e)
{
var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Run(async () =>
{
try
{
await Task.Factory.StartNew(
() => Test(),
CancellationToken.None,
TaskCreationOptions.None,
uiTaskScheduler);
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
}
});
}