2012-10-09 175 views
0

我运行下面的代码,当我点击一个按钮:SmartThreadPool阻塞UI线程

   foreach (string item in urlQueue) 
       { 

        log("creating job " + iia.ToString()); 
        _smartThreadPool.QueueWorkItem(
         new Amib.Threading.Func<string, int, int, string, int>(checkURLSmart), 
         item, iia, 5000, kryptonTextBox1.Text); 

        iia++; 
       } 

       Application.DoEvents(); 

       _smartThreadPool.Start(); 

       _smartThreadPool.WaitForIdle(); 
       _smartThreadPool.Shutdown(); 

出于某种原因,这是阻塞UI线程,任何想法如何解决这一问题?我希望UI在队列工作时能够响应

+0

'ThreadPool.WaitForIdle()' - 做GUI事件处理程序不等待。 –

+0

我可以在哪里开火? – Elvin

+0

不在GUI事件处理程序中。一种方法是对使用WaitAll()方法的工作项进行排队,以等待循环中发出的所有其他WorkItem,并向PostExecute中的GUI线程(PostMessage(),BeginInvoke(),whatever)发出完成信号'WaitAll'workItem的回调。 –

回答

0

您不应该在GUI线程中调用WaitForIdle()。 在.NET中使用http://msdn.microsoft.com/en-us/library/a06c0dc2.aspx或使用Java中的http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html invokeLater()代替。

该机制将您的代码放入队列以在GUI线程中执行。因此,您可以使用回调参数中的处理数据更新GUI视图。

也看到调用&的BeginInvoke之间的差异说明:What's the difference between Invoke() and BeginInvoke()

+0

我将如何使用WaitForIdle?只有为了控制才发现? – Elvin

+0

为什么你需要调用WaitForIdle?我想你以后执行一些更新逻辑。所以更好的是使用适当的框架机制从背景线程更新UI。 – Taky