我有这样的代码:
if (condition#1) {
// step 2
ConfigurazioneSA csa = new ConfigurazioneSA(...);
WconfiguraSA.RunWorkerAsync(csa);
}
else
{
// step 1
PassaggioIE bo = new PassaggioIE(...);
WpassIE.RunWorkerAsync(bo);
if (condition#2) {
// step 2
ConfigurazioneSA csa = new ConfigurazioneSA(...);
WconfiguraSA.RunWorkerAsync(csa);
}
}
当执行流程在condition#1
分支内部时,先前已执行step 1
块(在我之前的应用程序执行中),因此step 2
可以毫无问题地执行。
但是,当执行流程在else
分支内部时,我需要执行step 1
,当此步骤完成后,我可以执行step 2
。由于我使用BackgroundWorker
作为第1步启动,step 2
会在导致错误后立即启动。
我会将这个生产者/消费者问题同步化为尽可能少的熵。我发现的所有解决方案都引入了大量代码,而我只是简单的信号量,在step 2
未完成之前避免执行step 1
。有什么想法吗?
答案 0 :(得分:1)
我建议您使用Tpl
。这很容易实现。
Task.Factory.StartNew(() =>
{
//Step1
}).ContinueWith(antecedent => //executed after step1 is done
{
if (condition#2)
{
// step 2
}
});
另请注意,您不会获得Progress
和Completed
等事件,您必须牺牲。 Completed
事件类似于ContinuationTask
。
这里的另一个区别是ContinuationTask
将在线程池线程中执行,如果你想在UI线程中使用它TaskScheduler.FromCurrentSynchronizationContext
答案 1 :(得分:0)
如果您不想使用任务,则可以在执行完成时使用BackgroundWorker.RunWorkerCompleted
事件。
// step 1
PassaggioIE bo = new PassaggioIE(...);
WpassIE.RunWorkerCompleted += (sender, e) => {
// You might want to add error handling code here.
if (condition#2) {
// step 2
ConfigurazioneSA csa = new ConfigurazioneSA(...);
WconfiguraSA.RunWorkerAsync(csa);
}
}
WpassIE.RunWorkerAsync(bo);
但我认为使用TPL也更好。
答案 2 :(得分:0)
IsBusy
示例:
else
{
// step 1
PassaggioIE bo = new PassaggioIE(...);
WpassIE.RunWorkerAsync(bo);
// wait for WpassIE to complete
while(WpassIE.IsBusy) Application.DoEvents();
if (condition#2) {
// step 2
ConfigurazioneSA csa = new ConfigurazioneSA(...);
WconfiguraSA.RunWorkerAsync(csa);
}
}
在此解决方案中,您必须等待WpassIE完成。
并且不要使用Thread.Sleep
代替Application.DoEvents
,因为它会导致问题BackgroundWorkers never stop being busy。