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

时间:2011-05-11 23:24:45

标签: c# wpf multithreading thread-safety task-parallel-library

使用Thread非常简单

 Thread thread = new Thread(MethodWhichRequiresSTA);
 thread.SetApartmentState(ApartmentState.STA);  

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

Task.Factory.StartNew
  (
    () => 
    {return "some Text";}
  )
   .ContinueWith(r => AddControlsToGrid(r.Result));  

我正在使用

获取InvalidOperationException
  

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

3 个答案:

答案 0 :(得分:71)

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

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

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(...)
            .ContinueWith(r => AddControlsToGrid(r.Result), scheduler);

答案 1 :(得分:29)

对于未来寻找问题真实意图的访客:

答案 2 :(得分:0)

Dispatcher.Invoke 可能是一个解决方案。例如

    private async Task<bool> MyActionAsync()
    {
        // await for something, then return true or false
    }
    private void StaContinuation(Task<bool> t)
    {
        myCheckBox.IsChecked = t.Result;
    }
    private void MyCaller()
    {
        MyActionAsync().ContinueWith((t) => Dispatcher.Invoke(() => StaContinuation(t)));
    }