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>
|
/// <summary>
|
||||||
/// Dispatches the given action to be run on the UI thread asynchronously, even if the current thread is the UI thread
|
/// Dispatches the given action to be run on the UI thread asynchronously, even if the current thread is the UI thread
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="action">Action to run on the UI thread</param>
|
||||||
public static void PostToUIThread(Action action)
|
public static void PostToUIThread(Action action)
|
||||||
{
|
{
|
||||||
EnsureDispatcher();
|
EnsureDispatcher();
|
||||||
|
@ -93,9 +94,29 @@ namespace Stylet
|
||||||
action();
|
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>
|
/// <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
|
/// 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>
|
/// </summary>
|
||||||
|
/// <param name="action">Action to run on the UI thread</param>
|
||||||
public static void OnUIThread(Action action)
|
public static void OnUIThread(Action action)
|
||||||
{
|
{
|
||||||
EnsureDispatcher();
|
EnsureDispatcher();
|
||||||
|
@ -108,6 +129,7 @@ namespace Stylet
|
||||||
/// <summary>
|
/// <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
|
/// 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>
|
/// </summary>
|
||||||
|
/// <param name="action">Action to run on the UI thread</param>
|
||||||
public static void OnUIThreadSync(Action action)
|
public static void OnUIThreadSync(Action action)
|
||||||
{
|
{
|
||||||
EnsureDispatcher();
|
EnsureDispatcher();
|
||||||
|
@ -138,10 +160,23 @@ namespace Stylet
|
||||||
/// <summary>
|
/// <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
|
/// 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>
|
/// </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)
|
public static Task OnUIThreadAsync(Action action)
|
||||||
{
|
{
|
||||||
EnsureDispatcher();
|
EnsureDispatcher();
|
||||||
if (!TestExecuteSynchronously && !Dispatcher.IsCurrent)
|
if (!TestExecuteSynchronously && !Dispatcher.IsCurrent)
|
||||||
|
{
|
||||||
|
return PostOnUIThreadInternalAsync(action);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
return Task.FromResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Task PostOnUIThreadInternalAsync(Action action)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<object>();
|
var tcs = new TaskCompletionSource<object>();
|
||||||
Dispatcher.Post(() =>
|
Dispatcher.Post(() =>
|
||||||
|
@ -158,12 +193,6 @@ namespace Stylet
|
||||||
});
|
});
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
action();
|
|
||||||
return Task.FromResult(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determing if we're currently running in design mode
|
/// Determing if we're currently running in design mode
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void OnUIThreadExecutesUsingDispatcher()
|
public void OnUIThreadSyncExecutesUsingDispatcher()
|
||||||
{
|
{
|
||||||
var sync = new Mock<IDispatcher>();
|
var sync = new Mock<IDispatcher>();
|
||||||
Execute.Dispatcher = sync.Object;
|
Execute.Dispatcher = sync.Object;
|
||||||
|
@ -38,7 +38,22 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[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>();
|
var sync = new Mock<IDispatcher>();
|
||||||
Execute.Dispatcher = sync.Object;
|
Execute.Dispatcher = sync.Object;
|
||||||
|
@ -55,7 +70,26 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[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>();
|
var sync = new Mock<IDispatcher>();
|
||||||
Execute.Dispatcher = sync.Object;
|
Execute.Dispatcher = sync.Object;
|
||||||
|
@ -91,7 +125,7 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void OnUIThreadPropagatesException()
|
public void OnUIThreadSyncPropagatesException()
|
||||||
{
|
{
|
||||||
var sync = new Mock<IDispatcher>();
|
var sync = new Mock<IDispatcher>();
|
||||||
Execute.Dispatcher = sync.Object;
|
Execute.Dispatcher = sync.Object;
|
||||||
|
@ -125,21 +159,45 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[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;
|
Execute.Dispatcher = null;
|
||||||
Assert.Throws<InvalidOperationException>(() => Execute.PostToUIThread(() => { }));
|
Assert.Throws<InvalidOperationException>(() => Execute.PostToUIThread(() => { }));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ThrowsIfBeginOnUIThreadOrSynchronousCalledWithNoDispatcher()
|
public void ThrowsIfPostToUIThreadAsyncCalledWithNoDispatcher()
|
||||||
|
{
|
||||||
|
Execute.Dispatcher = null;
|
||||||
|
Assert.Throws<InvalidOperationException>(() => Execute.PostToUIThreadAsync(() => { }));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ThrowsIfOnUIThreadCalledWithNoDispatcher()
|
||||||
{
|
{
|
||||||
Execute.Dispatcher = null;
|
Execute.Dispatcher = null;
|
||||||
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThread(() => { }));
|
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThread(() => { }));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ThrowsIfOnUIThreadCalledWithNoDispatcher()
|
public void ThrowsIfOnUIThreadSyncCalledWithNoDispatcher()
|
||||||
{
|
{
|
||||||
Execute.Dispatcher = null;
|
Execute.Dispatcher = null;
|
||||||
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThreadSync(() => { }));
|
Assert.Throws<InvalidOperationException>(() => Execute.OnUIThreadSync(() => { }));
|
||||||
|
@ -153,7 +211,7 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void BeginOnUIThreadExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
public void PostToUIThreadExecutesSynchronouslyIfTestExecuteSynchronouslySet()
|
||||||
{
|
{
|
||||||
Execute.TestExecuteSynchronously = true;
|
Execute.TestExecuteSynchronously = true;
|
||||||
|
|
||||||
|
@ -164,7 +222,19 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[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;
|
Execute.TestExecuteSynchronously = true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue