Tidy up Execute, and add a new method which dispatches asynchronously, or runs synchronously

This commit is contained in:
Antony Male 2014-04-23 21:49:54 +01:00
parent 7cc888d090
commit 559277d809
1 changed files with 37 additions and 6 deletions

View File

@ -12,24 +12,52 @@ namespace Stylet
{
public static class Execute
{
/// <summary>
/// Should be set to the UI thread's SynchronizationContext. This is normally done by the Bootstrapper.
/// </summary>
public static SynchronizationContext SynchronizationContext;
private static bool? inDesignMode;
public static Action<Action> DefaultPropertyChangedDispatcher = Execute.OnUIThread;
/// <summary>
/// Default dispatcher used by PropertyChangedBase instances. Defaults to BeginOnUIThreadOrSynchronous
/// </summary>
public static Action<Action> DefaultPropertyChangedDispatcher = Execute.BeginOnUIThreadOrSynchronous;
private static void EnsureSynchronizationContext()
{
if (SynchronizationContext == null)
throw new Exception("Execute.SynchronizationContext must be set before this method can be called. This should normally have been done by the Bootstrapper");
}
/// <summary>
/// Dispatches the given action to be run on the UI thread, even if the current thread is the UI thread
/// </summary>
public static void BeginOnUIThread(Action action)
{
// If we're already on the given SynchronizationContext, or it hasn't been set, run synchronously
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current)
EnsureSynchronizationContext();
SynchronizationContext.Post(_ => action(), null);
}
/// <summary>
/// Dispatches the given action to be run on the UI thread, or runs it synchronously if the current thread is the UI thread
/// </summary>
public static void BeginOnUIThreadOrSynchronous(Action action)
{
EnsureSynchronizationContext();
if (SynchronizationContext != SynchronizationContext.Current)
SynchronizationContext.Post(_ => action(), null);
else
action();
}
/// <summary>
/// Dispatches the given action to be run on the UI thread and blocks until it completes, or runs it synchronously if the current thread is the UI thread
/// </summary>
public static void OnUIThread(Action action)
{
EnsureSynchronizationContext();
Exception exception = null;
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current)
if (SynchronizationContext != SynchronizationContext.Current)
{
SynchronizationContext.Send(_ =>
{
@ -52,10 +80,13 @@ namespace Stylet
}
}
/// <summary>
/// Dispatches the given action to be run on the UI thread and returns a task that completes when the action completes, or runs it synchronously if the current thread is the UI thread
/// </summary>
public static Task OnUIThreadAsync(Action action)
{
// If we're already on the given SynchronizationContext, or it hasn't been set, run synchronously
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current)
EnsureSynchronizationContext();
if (SynchronizationContext != SynchronizationContext.Current)
{
var tcs = new TaskCompletionSource<object>();
SynchronizationContext.Post(_ =>