如何创建运行STA线程的任务(TPL)?

Mic*_*ana 72 c# wpf multithreading thread-safety task-parallel-library

使用Thread非常简单

 Thread thread = new Thread(MethodWhichRequiresSTA);
 thread.SetApartmentState(ApartmentState.STA);  
Run Code Online (Sandbox Code Playgroud)

如何使用WPF应用程序中的任务完成相同的操作?这是一些代码:

Task.Factory.StartNew
  (
    () => 
    {return "some Text";}
  )
   .ContinueWith(r => AddControlsToGrid(r.Result));  
Run Code Online (Sandbox Code Playgroud)

我收到了一个InvalidOperationException

调用线程必须是STA,因为许多UI组件都需要这个.

dtb*_*dtb 72

您可以使用TaskScheduler.FromCurrentSynchronizationContext方法获取当前同步上下文的TaskScheduler(当您运行WPF应用程序时,它是WPF调度程序).

然后使用接受TaskScheduler 的ContinueWith重载:

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(...)
            .ContinueWith(r => AddControlsToGrid(r.Result), scheduler);
Run Code Online (Sandbox Code Playgroud)

  • 作为澄清的一点,实例方法Task.Start()也有一个重载,它接受一个TaskScheduler.问题的细节清楚地表明我们对延续案例更感兴趣,但是关于如何在STA线程上运行任务的更一般的问题不仅限于这种情况.我错误地假设一开始我需要从空的"软糖"任务继续,以便运行我想要的STA任务. (11认同)
  • 只是为了清楚; 只有ContinueWith方法中的lambda才会运行正确的上下文,而不是在主任务lambda中运行的lambda. (10认同)
  • 所以不应该编辑这个问题的标题以更好地反映其意图吗? (2认同)

Mrc*_*ief 32

对于任何未来寻找问题真实意图的访问者: