如何检查多个后台工作程序是否已完成并更新UI线程?

时间:2016-05-23 22:53:15

标签: wpf

我正在创建一个WPF应用程序来收集日志。我使用不同的Backgroundworker来执行一些脚本。 Script1用于script1,Worker2用于script2,依此类推。当Backgroundworker完成RunworkerCompleted方法执行时。

那么,我该如何等待所有工人完成?完成所有这些工作后,我需要更新UI线程。

3 个答案:

答案 0 :(得分:1)

您可以尝试使用任务。

Task t1 = Task.Run(() =>
    {
        // Do something
    }
);

Task t2 = Task.Run(() =>
    {
        // Do something
    }
);

Task t3 = Task.Run(() =>
    {
        // Do something
    }
);

await Task.WhenAll(new Task[] { t1, t2, t3 }).ContinueWith((task) =>
    {
        // Do something when all three tasks have completed...
    }        
);

答案 1 :(得分:0)

这是一种等待所有BackgroundWorker个对象完成的方法。我希望您使用C#

    static void Main(string[] args)
    {
        int noOfbackgroundWorker = 5;
        WaitHandle[] waitHandles = new WaitHandle[noOfbackgroundWorker];
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < noOfbackgroundWorker; i++)
        {
            var bg1 = new BackgroundWorker();
            var handle = new EventWaitHandle(false, EventResetMode.ManualReset);
            bg1.DoWork += delegate(object sender, DoWorkEventArgs e) { Thread.Sleep(i * 1000); };
            bg1.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { handle.Set(); };
            waitHandles[i] = handle;
            bg1.RunWorkerAsync();
        }

        WaitHandle.WaitAll(waitHandles);
        Console.WriteLine("Done in "+sw.Elapsed.Seconds + " seconds");
        Console.ReadKey();
    }

除了上面没有BackgroundWorker之外,只需为每个工作人员设置一个bool变量来映射每个工作人员的完整状态,并从所有RunworkerCompleted事件处理程序中调用一个公共方法如果传递条件if(a && b && c.....),则通知UI

答案 2 :(得分:0)

正如我在Task.Run vs BackgroundWorker conclusion中所说的那样:

  使用Task.Run更容易waiting for two separate background operations to complete before doing something else之类的内容。几乎任何时候你必须协调后台操作,Task.Run代码将更多更简单!

(这是series of blog posts comparing Task.Run to BackgroundWorker)的结论。

  

Script1用于script1,Worker2用于script2,依此类推。

您可以使用Task.Run

执行此操作
Result DoWork(Script script) { ... }

IEnumerable<Script> scripts = ...;
var tasks = scripts.Select(x => Task.Run(() => DoWork(x))).ToList();
  

那么,我该如何等待所有工人完成?完成所有这些工作后,我需要更新UI线程。

使用awaitTask.WhenAll

var results = await Task.WhenAll(tasks);
... // Update UI with results