【问题标题】:is it possible to BackgroundWorker will wait to another?BackgroundWorker 是否有可能等待另一个?
【发布时间】:2012-03-22 23:50:53
【问题描述】:
foreach (string file in listToConvert)
{
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += new DoWorkEventHandler(
    (s3, e3) =>
    {
        newFile = sendFilesToConvert(file);
    });

    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
    (s3, e3) =>
    {
        listBoxFiles.Items.Add(newFile);
    });

    backgroundWorker.RunWorkerAsync();
}

列表中的每个文件都将转换为另一个文件,我希望每个 BackgroundWorker 将等到它完成转换,然后才开始下一个 BackgroundWorker 我该怎么做?

【问题讨论】:

  • 你为什么不想在一个BackgroundWorker中转换所有文件?
  • 那你为什么要使用后台工作者呢?无论哪种方式,您都可以简单地在前一个事件的已完成事件中启动新的后台工作人员。
  • 您使用的是什么版本的 .Net。如果您使用的是 4.0,则可以使用单个后台工作程序和一个并发队列。
  • @oxilumin 哦,您阅读了问题并实际查看了代码! :) 是的,那会更有意义。
  • 你能告诉我怎么做吗?我正在使用.Net 3.5

标签: c# .net-3.5


【解决方案1】:

不要在循环的每次运行中创建 Bgw。无论如何,这不是一个好主意。

只需在单个 Bgw 中运行 foreach()

您可以使用进度事件将结果添加到列表框或将它们收集到列表中,并在完成后一次性添加。

【讨论】:

  • 这比 ConcurrentQueue 的想法要好!
【解决方案2】:

您可以为此使用 TPL:

   Task<List<newFile>> task1 = Task<List<newFile>>.Factory.StartNew(() =>
   {
      List<newFile> newFiles = new List<newFile>();
     foreach(string file in fileList)
     {
        newFiles.Add(SendFilesToConvert(file));
     };

     return newFilesList;
   });


   foreach(newFile nFile in task1.Result)
   {
     listBoxFiles.Items.Add(nFile);
   };

【讨论】:

  • 我正在使用不包括任务的 .Net 3.5
【解决方案3】:

据我了解,您想在您的场景中更新一个 UI 元素 (listBoxFiles)。所以你可以使用下面的代码:

BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;

var context = SynchronizationContext.Current;
var filesList = // clone your listToConvert if it's not a local variable or other threads can access it

backgroundWorker.DoWork += (s3, e3) =>
               {
                   foreach (string file in filesList)
                   {
                       var newFile = sendFilesToConvert(file);
                       context.Post(x => listBoxFiles.Items.Add(newFile), null);

                       // Report progress
                   }
               };

backgroundWorker.RunWorkerAsync();

此代码每次需要更新您的 UI 控件时都会(异步)向您的 UI 线程发送一条消息,然后 UI 线程会调度它消息并在适当的上下文中执行代码 (ListBox.Items.Add(...))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 2021-08-17
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多