【发布时间】:2012-03-17 19:31:40
【问题描述】:
以下代码是实际应用程序中代码的简化。下面的问题是会在 UI 线程中运行长时间的工作,而不是在后台线程中运行。
void Do()
{
Debug.Assert(this.Dispatcher.CheckAccess() == true);
Task.Factory.StartNew(ShortUIWork, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
void ShortUIWork()
{
Debug.Assert(this.Dispatcher.CheckAccess() == true);
Task.Factory.StartNew(LongWork, TaskCreationOptions.LongRunning);
}
void LongWork()
{
Debug.Assert(this.Dispatcher.CheckAccess() == false);
Thread.Sleep(1000);
}
所以 Do() 通常从 UI 上下文中调用。由 TaskScheduler 定义的 ShortUIWork 也是如此。但是,LongWork 最终也会在 UI 线程中调用,这当然会阻塞 UI。
如何保证任务不在UI线程中运行?
【问题讨论】:
-
tasks根据定义创建一个不会在 UI 上运行的线程。你确定LongWork会阻塞 UI 线程吗? -
@Tigran:TPL 默认使用后台线程,而不是根据定义。
-
不能重现问题的代码无济于事。出现这种行为的一个常见原因是 COM 组件的包装类。 COM 通过自动将任何调用编组回创建它们的线程来保持类的对象不支持任何类型的线程安全。
-
代码为我重现了这个问题。
标签: c# wpf task-parallel-library