WaitAll不支持STA线程上的多个句柄

  1. 为什么我得到这个错误信息? “WaitAll在STA线程上的多个句柄不被支持”。
  2. 我应该使用[MTAThreadAttribute]属性? 更新:不用WPF应用程序!

注意:错误在WaitHandle.WaitAll(doneEvents); 我正在使用一个标准的WPF项目

private void Search() { const int CPUs = 2; var doneEvents = new ManualResetEvent[CPUs]; // Configure and launch threads using ThreadPool: for (int i = 0; i < CPUs; i++) { doneEvents[i] = new ManualResetEvent(false); var f = new Indexer(Paths[i], doneEvents[i]); ThreadPool.QueueUserWorkItem(f.WaitCallBack, i); } // Wait for all threads in pool WaitHandle.WaitAll(doneEvents); Debug.WriteLine("Search completed!"); } 

更新:以下解决scheme不适用于WPF应用程序! 无法将主应用程序属性更改为MTAThreadAttribute。 这将导致以下错误:

错误: “不支持WAA线程上的多个句柄的WaitAll。”

怎么样使用任务来为你做线程。

http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx

 var task1 = Task.Factory.StartNew(() => DoSomeWork()); var task2 = Task.Factory.StartNew(() => DoSomeWork()); var task3 = Task.Factory.StartNew(() => DoSomeWork()); Task.WaitAll(task1, task2, task3); 

其实我用下面的代替WaitHandle.WaitAll(doneEvents);

 foreach (var e in doneEvents) e.WaitOne(); 

使用一个ManualResetEvent并等待它。 还要维护一个TaskCountvariables,该variables设置为您启动的工作线程数量,在工作线程代码中使用Interlocked.Decrement作为工作人员的最后一个操作,并在计数器达到零时发出事件信号,例如

 // other worker actions... if (Interlocked.Decrement(ref taskCount) == 0) doneEvent.Set(); 

我会重构你的代码,而不是使用CountdownEvent类。

 private void Search() { const int CPUs = 2; var done = new CountdownEvent(1); // Configure and launch threads using ThreadPool: for (int i = 0; i < CPUs; i++) { done.AddCount(); var f = new Indexer(Paths[i], doneEvents[i]); ThreadPool.QueueUserWorkItem( (state) => { try { f.WaitCallBack(state); } finally { done.Signal(); } }, i); } // Wait for all threads in pool done.Signal(); done.Wait(); Debug.WriteLine("Search completed!"); } 

使用这样的东西:

 foreach (ITask Task in Tasks) { Task.WaitHandle = CompletedEvent; new Thread(Task.Run).Start(); } int TasksCount = Tasks.Count; for (int i = 0; i < TasksCount; i++) CompletedEvent.WaitOne(); if (AllCompleted != null) AllCompleted(this, EventArgs.Empty);