【发布时间】:2017-02-22 20:59:55
【问题描述】:
从 UI (thread1) 我想创建一个进度 UI(thread2)。 Progress UI 在 thread3 中创建一个任务并等待其完成。
任务(thread3)完成并调用关闭进度UI,必须在thread2中执行。
对于关闭操作,我使用 AsyncOperationManager 来捕获 thread2 的上下文,然后从 thread4 执行 POST 方法。
但关闭总是从另一个线程发生。
以下所有代码均来自 ProgressWindows 类。
_currentTask = new Progress<double>(Close); // I call this in progress UI constructor.
// This is invoked in constructor of Progress class which is used inside ProgressWindow.
_asyncOperation = AsyncOperationManager.CreateOperation(null);
public static void Run2(Action action)
{
Debug.WriteLine(":: Run2 in thread: {0}", Thread.CurrentThread.ManagedThreadId);
var th = new Thread(_ =>
{
Debug.WriteLine(":: StartNew in thread: {0}", Thread.CurrentThread.ManagedThreadId);
var progress = new ProgressWindow();
progress.Run(action);
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
public void Run(Action action)
{
Debug.WriteLine(":: Run in thread: {0}", Thread.CurrentThread.ManagedThreadId);
SetupProgressBar();
RunTask(action);
ShowDialog();
}
private void RunTask(Action action)
{
Task.Factory.StartNew(action).ContinueWith(_ => _currentTask.OnCompleted(null));
}
private void Close(object state)
{
Debug.WriteLine(":: Close in thread: {0}", Thread.CurrentThread.ManagedThreadId);
Hide();
Close();
}
问题是:
private void RunTask(Action action)
{
Task.Factory.StartNew(action).ContinueWith(_ => _currentTask.OnCompleted(null));
}
你看,_currentTask.OnCompleted(null) 是从另一个线程调用的,但 _currentTaskof 类型的 Progress 使用在 UI 线程中捕获的上下文,但 OnCompleted 总是从 UI 线程以外的另一个线程调用。为什么?它必须在相同的上下文中。
更新 1:
混合 System.Threading.SynchronizationContextt 与 System.Windows.Form.WindowsFormsSynchronizationContext 和 System.Windows.Threading.DispatcherSynchronizationContext
【问题讨论】:
-
您正在从后台线程调用
ContinueWith。你为什么认为它会将它编组到 UI 线程? -
因为在 ProgressWindow 的范围内我创建了 Progress,我在其中使用 AsyncOperationManager.CreateOperation 创建了 asyncOperation。我用 asyncOperation.Post 调用 OnCompleted。当然,这是相同的 UI 上下文......我想是的。
-
使用 Dispatcher.BeginInvoke 解决了所有问题,但我想知道为什么 SynchronizationContext 在这里会被忽略?
-
不确定,不熟悉
AsyncOperationManager。
标签: c# multithreading synchronization task-parallel-library