我正在创建一个WPF
应用程序来收集日志。我使用不同的Backgroundworker
来执行一些脚本。 Script1用于script1,Worker2用于script2,依此类推。当Backgroundworker
完成RunworkerCompleted
方法执行时。
那么,我该如何等待所有工人完成?完成所有这些工作后,我需要更新UI
线程。
答案 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线程。
使用await
和Task.WhenAll
:
var results = await Task.WhenAll(tasks);
... // Update UI with results