WaitAll不支持STA线程上的多个句柄
- 为什么我得到这个错误信息? “WaitAll在STA线程上的多个句柄不被支持”。
- 我应该使用[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);