WaitAll for multiple handles on a STA thread is not supported

孤人 提交于 2019-11-27 12:34:29

What about using the Tasks to do your threading for you.

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);
Calimero100582

Actually I use the following to replace WaitHandle.WaitAll(doneEvents);

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

Use one ManualResetEvent and wait on it. Also maintain a TaskCount variable that is set to the number of worker threads you start, use Interlocked.Decrement in the worker thread code as the very last action of the worker and signal the event if the counter reaches zero,e.g.

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

I would refactor your code to use the CountdownEvent class instead.

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!"); 
} 

use something like this:

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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!