NotSupportedException on WaitHandle.WaitAll

孤人 提交于 2019-12-19 21:59:28

问题


I am trying to execute the following code. The code tries to parallely download and save images. I pass a list of images to be downloaded. I wrote this in C# 3.0 and compiled it using .NET Framework 4 (VS.NET express edition). The WaitAll operation is resulting in a NotSupportedException (WaitAlll for multiple handles on a STA thread is not supported) everytime I try to run my program. I tried removing SetMaxThreads, but that didn't do any difference.

public static void SpawnThreads(List<string> imageList){
    imageList = new List<string>(imageList);
    ManualResetEvent[] doneEvents = new ManualResetEvent[imageList.Count];
    PicDownloader[] picDownloaders = new PicDownloader[imageList.Count];
    ThreadPool.SetMaxThreads(MaxThreadCount, MaxThreadCount);
    for (int i = 0; i < imageList.Count; i++) {
        doneEvents[i] = new ManualResetEvent(false);
        PicDownloader p = new PicDownloader(imageList[i], doneEvents[i]);
        picDownloaders[i] = p;
        ThreadPool.QueueUserWorkItem(p.DoAction);
    }
    // The following line is resulting in "NotSupportedException"     
    WaitHandle.WaitAll(doneEvents);
    Console.WriteLine("All pics downloaded");
}

Can you please let me understand what is the issue I am running into?

Thank you


回答1:


Did you mark one of the methods with [STAThread] attribute?




回答2:


I advise against using multiple WaitHandle instances to wait for completion. Use the CountdownEvent class instead. It results in more elegant and scalable code. Plus, the WaitHandle.WaitAll method only supports up to 64 handles and cannot be called on an STA thread. By refactoring your code to use the canonical pattern I came up with this.

public static void SpawnThreads(List<string> imageList)
{ 
  imageList = new List<string>(imageList); 
  var finished = new CountdownEvent(1);
  var picDownloaders = new PicDownloader[imageList.Count]; 
  ThreadPool.SetMaxThreads(MaxThreadCount, MaxThreadCount); 
  for (int i = 0; i < imageList.Count; i++) 
  { 
    finished.AddCount();    
    PicDownloader p = new PicDownloader(imageList[i]); 
    picDownloaders[i] = p; 
    ThreadPool.QueueUserWorkItem(
      (state) =>
      {
        try
        {
          p.DoAction
        }
        finally
        {
          finished.Signal();
        }
      });
  } 
  finished.Signal();
  finished.Wait();
  Console.WriteLine("All pics downloaded"); 
} 



回答3:


Have you tried setting the apartment state for the thread?

thread.SetApartmentState (System.Threading.Apartmentstate.MTA );


来源:https://stackoverflow.com/questions/3784510/notsupportedexception-on-waithandle-waitall

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