我将 Caliburn Micro 的协程用于在 WPF 中也显示屏幕的工作流。
我为繁忙的屏幕制作了这个 IDisposable 构造:围绕一个长时间运行的作业包装 using 语句,并且在该作业期间将显示一个繁忙的屏幕。当 using 块结束时, Dispose() 将在幕后隐藏繁忙的屏幕。
using-scope 构造使用 .. 显示和隐藏繁忙的屏幕
Application.Current.Dispatcher.Invoke(...show/hide form...)
.. 让它在 UI 线程上发生:
使用示例:
yield return new TaskResult(Task.Factory.StartNew(() =>
{
using (_dialogController.ShowDialogForUsingScope(new BusyViewModel()
{ Message = "Account gegevens ophalen..." }))
{
_securityContext.RefreshAccountFromServer();
}
using (_dialogController.ShowDialogForUsingScope(new BusyViewModel()
{ Message = "You see me..." }))
{
_securityContext.RefreshAccountFromServer();
}
}));
这完美地工作:显示繁忙的屏幕,工作完成,它被删除,紧接着在第二个工作期间另一个繁忙的屏幕并完成:)
但是,当我使用 2 次收益返回时,第二个作业无论如何都会在 UI 线程上运行:
Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground);
yield return new TaskResult(Task.Factory.StartNew(() =>
{
Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground);
using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() { Message = "Account gegevens ophalen..." }, 2000))
{
_securityContext.RefreshAccountFromServer();
}
}));
Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground);
yield return new TaskResult(Task.Factory.StartNew(() =>
{
Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground);
using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() { Message = "You never see me..." }, 2000))
{
}
}));
导致:
Thread: 9, IsBackground: False
Thread: 12, IsBackground: True
Thread: 9, IsBackground: False
Thread: 9, IsBackground: False --> 9 too ??
这解释了为什么它会冻结,但为什么任务不在另一个线程上?