C# 同步后台工作程序
我有这样一个代码:C# 同步后台工作程序,c#,backgroundworker,.net-4.5,C#,Backgroundworker,.net 4.5,我有这样一个代码: 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) {
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);
}
}
当执行流在条件#1
分支内时,步骤1
块先前已执行(在我的应用程序的先前执行中),因此步骤2
可以毫无问题地执行
但是,当执行流在else
分支内时,我需要执行步骤1
,当此步骤完成时,我可以执行步骤2
。由于我使用BackgroundWorker
作为步骤1的开始,因此步骤2
在导致错误后立即开始
我会把生产者/消费者的问题记录下来,尽可能减少熵。我发现的所有解决方案都会引入大量代码,而我只需要一个信号量,在
步骤1
未完成之前避免执行步骤2
。有什么想法吗?我建议您为此使用Tpl
。这是很容易做到的
Task.Factory.StartNew(() =>
{
//Step1
}).ContinueWith(antecedent => //executed after step1 is done
{
if (condition#2)
{
// step 2
}
});
还要注意的是,您不会得到像进度
和完成
这样的事件,您必须做出牺牲<代码>已完成事件类似于继续任务
这里的另一个区别是ContinuationTask
将在线程池线程中执行,如果您希望它在UI线程中使用TaskScheduler.FromCurrentSynchronizationContext
如果不想使用任务,则可以使用在其执行完成时引发的事件
//步骤1
帕萨戈伊波=新帕萨戈伊(…);
WpassIE.RunWorkerCompleted+=(发件人,e)=>{
//您可能希望在此处添加错误处理代码。
如果(条件#2){
//步骤2
ConfigurazioneSA csa=新的ConfigurazioneSA(…);
WconfiguraSA.RunWorkerAsync(csa);
}
}
WpassIE.RunWorkerAsync(bo);
但我认为使用第三方物流也更好。
很忙
示例:
else
{
//第一步
帕萨戈伊波=新帕萨戈伊(…);
WpassIE.RunWorkerAsync(bo);
//等待WpassIE完成
while(WpassIE.IsBusy)Application.DoEvents();
如果(条件#2){
//步骤2
ConfigurazioneSA csa=新的ConfigurazioneSA(…);
WconfiguraSA.RunWorkerAsync(csa);
}
}
在这个解决方案中,您必须等待WpassIE完成
不要使用
Thread.Sleep
而不是Application.DoEvents
,因为它会导致这样的问题。我已经在我的else分支中插入了你的代码,然后用真实的代码替换了步骤1和步骤2,但似乎已经不同步了:(我无法理解你,发生了什么事?什么都没有。步骤1一开始,步骤2也开始了(导致与之前相同的错误)…将步骤1和步骤2替换为DoWork
处理程序中的代码,而不是RunWorkerAsync
。是的,unarist是正确的,您必须在步骤1中使用DoWork
中的代码。RunWorkerCompleted是否会与以前的RunWorkerCompleted造成混乱?哦,我认为bo
是Backgroundorker…如果您使用相同的Backgroundorker ma是的,是的。对于解决方法,将lambda表达式另存为委托,然后您可以将其从RunWorkerCompleted
中删除。如果您可以在步骤1时阻止此方法,BackgroundWorker.IsBusy
非常有用。我是否应该在(!BackgroundWorker.IsBusy){//step 2}时编写类似的代码(!BackgroundWorker.IsBusy)Application.DoEvents();
。请参阅。