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 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; public static SynchronizationContext SynchronizationContext;
private static bool? inDesignMode; 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) public static void BeginOnUIThread(Action action)
{ {
// If we're already on the given SynchronizationContext, or it hasn't been set, run synchronously EnsureSynchronizationContext();
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current) 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); SynchronizationContext.Post(_ => action(), null);
else else
action(); 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) public static void OnUIThread(Action action)
{ {
EnsureSynchronizationContext();
Exception exception = null; Exception exception = null;
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current) if (SynchronizationContext != SynchronizationContext.Current)
{ {
SynchronizationContext.Send(_ => 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) public static Task OnUIThreadAsync(Action action)
{ {
// If we're already on the given SynchronizationContext, or it hasn't been set, run synchronously EnsureSynchronizationContext();
if (SynchronizationContext != null && SynchronizationContext != SynchronizationContext.Current) if (SynchronizationContext != SynchronizationContext.Current)
{ {
var tcs = new TaskCompletionSource<object>(); var tcs = new TaskCompletionSource<object>();
SynchronizationContext.Post(_ => SynchronizationContext.Post(_ =>