2010-09-24 29 views
4

我想执行下面的代码。该代码尝试并行下载并保存图像。我传递要下载的图像列表。我在C#3.0中编写了这个代码,并使用.NET Framework 4(VS.NET express edition)编译它。 WaitAll操作产生了一个NotSupportedException(对于STA线程上的多个句柄的WaitAlll不受支持)每当我尝试运行我的程序时。我试图删除SetMaxThreads,但这没有任何区别。NotSupportedException在WaitHandle.WaitAll

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

你能让我明白我遇到的问题是什么?

谢谢

回答

5

您是否标记了[STAThread]属性的方法之一?

+0

谢谢Danny!主应用程序线程确实标记为[STAThread]。我删除它,像魔术般运作。为什么VS.NET将所有的入口方法默认为[STAThread]? – rkg 2010-09-24 06:04:53

+0

@Ravi:我不认为这个属性默认会被标记为'main'。也许它是由你自己标记的? – 2010-09-24 06:12:19

+0

我知道这有点旧了,但是在VS2012 Express for Desktop中 - 我从零开始创建了一个全新的应用程序,实际上在Program.cs文件中,Main用STAThread属性进行了装饰。我删除它,现在它适用于我。多谢你们! – Losbear 2013-05-15 16:28:54

0

您是否尝试设置单元状态的线程?

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

谢谢,但我只是创建一个ThreadPool,而不是个人的线程! ThreadPool不允许我设置ApartmentState。 – rkg 2010-09-24 05:55:05

7

我建议不要使用多个WaitHandle实例来等待完成。改为使用CountdownEvent类。它产生更优雅和可扩展的代码。另外,WaitHandle.WaitAll方法最多只支持64个句柄,不能在STA线程上调用。通过重构你的代码来使用规范模式,我想出了这个。

​​3210
+0

谢谢Brian。将尝试一下。 – rkg 2010-09-24 19:52:37

相关问题