当我必须做许多与 GUI 合作的短任务时,我应该BackgroundWorker
为每个任务使用另一个,还是其他一些解决方案?
编辑
我的意思是每 5 秒更新一次 datagridview 中的每个单元格(200 行 x 50 列)。每个单元格都存储图像。
当我必须做许多与 GUI 合作的短任务时,我应该BackgroundWorker
为每个任务使用另一个,还是其他一些解决方案?
编辑
我的意思是每 5 秒更新一次 datagridview 中的每个单元格(200 行 x 50 列)。每个单元格都存储图像。
当我处理许多小任务时,我倾向于发现这ThreadPool
是处理它们的好方法。您可以像这样在后台线程上分派委托:
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc));
您还可以将对象作为状态传递给线程,考虑将对象作为参数的委托。你可以这样称呼:
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc), state);
其中 state 是您的线程知道如何处理的某个对象。
编辑:一种ThreadPool
方法应该适用于您的场景。只需确保必须在 GUI 线程上调用任何更改您的 GUI 的代码,否则您将获得一些跨线程异常。
BackgroundWorker
会更适合长时间运行的任务,你想要像ThreadPool这样的东西。这是一个非常粗略的例子:
QueueUserWorkItem
允许您指定一个工作方法并传入一个对象以供该方法使用。
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), object);
然后,您将拥有DoWork
所有神奇发生的方法:
public void DoWork(object sender)
{
object s = (object)sender;
this.Invoke(new ThreadDone(ReportProgress), result);
}
请注意对this.Invoke(new TaskDone(ReportProgress));
This 的调用安全地调用在主线程上运行的代码,以使用来自DoWork
. 这是通过私人代表完成的:
private delegate void ThreadDone(object yourObject);
哪个会调用:
private void ReportProgress(object yourObject)
{
//update UI
}
您还可以通过跟踪Interlocked
计数器对象来使用它来检查任务何时完成,例如
foreach (string s in strings)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), s);
Interlocked.Increment(ref workItems);
}
然后减少workItems
单个线程完成的时间并简单检查何时workItems == 0
Interlocked.Decrement(ref workItems);
if (workItems == 0)
{
this.Invoke(new TaskDone(WorkComplete));
}
希望这可以帮助。