0

当我必须做许多与 GUI 合作的短任务时,我应该BackgroundWorker为每个任务使用另一个,还是其他一些解决方案?

编辑

我的意思是每 5 秒更新一次 datagridview 中的每个单元格(200 行 x 50 列)。每个单元格都存储图像。

4

2 回答 2

2

当我处理许多小任务时,我倾向于发现这ThreadPool是处理它们的好方法。您可以像这样在后台线程上分派委托:

ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc));

您还可以将对象作为状态传递给线程,考虑将对象作为参数的委托。你可以这样称呼:

ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc), state);

其中 state 是您的线程知道如何处理的某个对象。

编辑:一种ThreadPool方法应该适用于您的场景。只需确保必须在 GUI 线程上调用任何更改您的 GUI 的代码,否则您将获得一些跨线程异常。

于 2012-08-10T11:17:07.257 回答
2

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

希望这可以帮助。

于 2012-08-10T11:31:55.523 回答