mirror of https://github.com/AMT-Cheif/Stylet.git
Add Execute.PostToUIThreadAsync
This commit is contained in:
parent
a7a63d5ae1
commit
642a038488
|
@ -84,6 +84,7 @@ namespace Stylet
|
|||
/// <summary>
|
||||
/// Dispatches the given action to be run on the UI thread asynchronously, even if the current thread is the UI thread
|
||||
/// </summary>
|
||||
/// <param name="action">Action to run on the UI thread</param>
|
||||
public static void PostToUIThread(Action action)
|
||||
{
|
||||
EnsureDispatcher();
|
||||
|
@ -93,9 +94,29 @@ namespace Stylet
|
|||
action();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches the given action to be run on the UI thread asynchronously, and returns a task which completes when the action completes, even if the current thread is the UI thread
|
||||
/// </summary>
|
||||
/// <param name="action">Action to run on the UI thread</param>
|
||||
/// <returns>Task which completes when the action has been run</returns>
|
||||
public static Task PostToUIThreadAsync(Action action)
|
||||
{
|
||||
EnsureDispatcher();
|
||||
if (!TestExecuteSynchronously)
|
||||
{
|
||||
return PostOnUIThreadInternalAsync(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches the given action to be run on the UI thread asynchronously, or runs it synchronously if the current thread is the UI thread
|
||||
/// </summary>
|
||||
/// <param name="action">Action to run on the UI thread</param>
|
||||
public static void OnUIThread(Action action)
|
||||
{
|
||||
EnsureDispatcher();
|
||||
|
@ -108,6 +129,7 @@ namespace Stylet
|
|||
/// <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>
|
||||
/// <param name="action">Action to run on the UI thread</param>
|
||||
public static void OnUIThreadSync(Action action)
|
||||
{
|
||||
EnsureDispatcher();
|
||||
|
@ -138,25 +160,14 @@ 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>
|
||||
/// <param name="action">Action to run on the UI thread</param>
|
||||
/// <returns>Task which completes when the action has been run</returns>
|
||||
public static Task OnUIThreadAsync(Action action)
|
||||
{
|
||||
EnsureDispatcher();
|
||||
if (!TestExecuteSynchronously && !Dispatcher.IsCurrent)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
Dispatcher.Post(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
tcs.SetException(e);
|
||||
}
|
||||
});
|
||||
return tcs.Task;
|
||||
return PostOnUIThreadInternalAsync(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,6 +176,24 @@ namespace Stylet
|
|||
}
|
||||
}
|
||||
|
||||
private static Task PostOnUIThreadInternalAsync(Action action)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
Dispatcher.Post(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
tcs.SetException(e);
|
||||
}
|
||||
});
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determing if we're currently running in design mode
|
||||
/// </summary>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void OnUIThreadExecutesUsingDispatcher()
|
||||
public void OnUIThreadSyncExecutesUsingDispatcher()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
@ -38,7 +38,22 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void BeginOnUIThreadExecutesUsingDispatcher()
|
||||
public void OnUIThreadSyncExecutesSynchronouslyIfDispatcherIsCurrent()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
||||
sync.SetupGet(x => x.IsCurrent).Returns(true);
|
||||
|
||||
bool actionCalled = false;
|
||||
Execute.OnUIThreadSync(() => actionCalled = true);
|
||||
|
||||
Assert.IsTrue(actionCalled);
|
||||
sync.Verify(x => x.Send(It.IsAny<Action>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PostToUIThreadExecutesUsingDispatcher()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
@ -55,7 +70,26 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void BeginOnUIThreadOrSynchronousExecutesUsingDispatcherIfNotCurrent()
|
||||
public void PostToUIThreadAsyncExecutesUsingDispatcher()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
||||
Action passedAction = null;
|
||||
sync.Setup(x => x.Post(It.IsAny<Action>())).Callback((Action a) => passedAction = a);
|
||||
|
||||
bool actionCalled = false;
|
||||
var task = Execute.PostToUIThreadAsync(() => actionCalled = true);
|
||||
|
||||
Assert.IsFalse(task.IsCompleted);
|
||||
Assert.IsFalse(actionCalled);
|
||||
passedAction();
|
||||
Assert.IsTrue(actionCalled);
|
||||
Assert.IsTrue(task.IsCompleted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnUIThreadExecutesUsingDispatcherIfNotCurrent()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
@ -91,7 +125,7 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void OnUIThreadPropagatesException()
|
||||
public void OnUIThreadSyncPropagatesException()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
@ -125,21 +159,45 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfBeginOnUIThreadCalledWithNoDispatcher()
|
||||
public void PostToUIThreadAsyncPrepagatesException()
|
||||
{
|
||||
var sync = new Mock<IDispatcher>();
|
||||
Execute.Dispatcher = sync.Object;
|
||||
|
||||
Action passedAction = null;
|
||||
sync.Setup(x => x.Post(It.IsAny<Action>())).Callback((Action a) => passedAction = a);
|
||||
|
||||
var ex = new Exception("test");
|
||||
var task = Execute.PostToUIThreadAsync(() => { throw ex; });
|
||||
|
||||
passedAction();
|
||||
Assert.IsTrue(task.IsFaulted);
|
||||
Assert.AreEqual(ex, task.Exception.InnerExceptions[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfPostToUIThreadCalledWithNoDispatcher()
|
||||
{
|
||||
Execute.Dispatcher = null;
|
||||
Assert.Throws<InvalidOperationException>(() => Execute.PostToUIThread(() => { }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfBeginOnUIThreadOrSynchronousCalledWithNoDispatcher()
|
||||
public void ThrowsIfPostToUIThreadAsyncCalledWithNoDispatcher()
|
||||
{
|
||||
Execute.Dispatcher = null;
|
||||
Assert.Throws<InvalidOperationException>(() => Execute.PostToUIThreadAsync(() => { }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfOnUIThreadCalledWithNoDispatcher()
|
||||
{
|
||||
Execute.Dispatcher = null;
|
||||
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThread(() => { }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfOnUIThreadCalledWithNoDispatcher()
|
||||
public void ThrowsIfOnUIThreadSyncCalledWithNoDispatcher()
|
||||
{
|
||||
Execute.Dispatcher = null;
|
||||
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThreadSync(() => { }));
|
||||
|
@ -153,7 +211,7 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void BeginOnUIThreadExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||
public void PostToUIThreadExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||
{
|
||||
Execute.TestExecuteSynchronously = true;
|
||||
|
||||
|
@ -164,7 +222,19 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void OnUIThreadExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||
public void PostToUIThreadAsyncExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||
{
|
||||
Execute.TestExecuteSynchronously = true;
|
||||
|
||||
Execute.Dispatcher = null;
|
||||
bool called = false;
|
||||
var task = Execute.PostToUIThreadAsync(() => called = true);
|
||||
Assert.True(called);
|
||||
Assert.True(task.IsCompleted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnUIThreadSyncExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||
{
|
||||
Execute.TestExecuteSynchronously = true;
|
||||
|
||||
|
|
Loading…
Reference in New Issue