C# 如何防止在后台任务完成之前向前移动?
我有一个外部库,它有一个在后台线程上执行长时间运行任务的方法。完成后,它会在启动该方法的线程(通常是UI线程)上触发一个已完成事件。看起来是这样的:C# 如何防止在后台任务完成之前向前移动?,c#,winforms,multithreading,c#-3.0,synchronization,C#,Winforms,Multithreading,C# 3.0,Synchronization,我有一个外部库,它有一个在后台线程上执行长时间运行任务的方法。完成后,它会在启动该方法的线程(通常是UI线程)上触发一个已完成事件。看起来是这样的: public class Foo { public delegate void CompletedEventHandler(object sender, EventArgs e); public event CompletedEventHandler Completed; public void LongRunningTa
public class Foo
{
public delegate void CompletedEventHandler(object sender, EventArgs e);
public event CompletedEventHandler Completed;
public void LongRunningTask()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(5000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Completed != null)
Completed(this, EventArgs.Empty);
}
}
private void button1_Click(object sender, EventArgs e)
{
Foo b = new Foo();
b.Completed += new Foo.CompletedEventHandler(b_Completed);
b.LongRunningTask();
Debug.WriteLine("It's all done");
}
void b_Completed(object sender, EventArgs e)
{
// do stuff
}
调用此库的代码如下所示:
public class Foo
{
public delegate void CompletedEventHandler(object sender, EventArgs e);
public event CompletedEventHandler Completed;
public void LongRunningTask()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(5000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Completed != null)
Completed(this, EventArgs.Empty);
}
}
private void button1_Click(object sender, EventArgs e)
{
Foo b = new Foo();
b.Completed += new Foo.CompletedEventHandler(b_Completed);
b.LongRunningTask();
Debug.WriteLine("It's all done");
}
void b_Completed(object sender, EventArgs e)
{
// do stuff
}
在button1_Click方法中,在我调用b.LongRunningTask()之后,完成的事件在5秒后在UI线程上触发,我更新了UI,一切都很好,因为我不必处理将内容封送到适当的线程
但是,我现在需要同步进程(不更改外部库)。换句话说,在我启动.LongRunningTask方法之后,该方法中的下一条有意义的语句应该在.LongRunningTask完成后触发
我曾经尝试过使用EventWaitHandle(例如,在调用LongRunningTask后执行WaitOne,然后在已完成的事件中重置它,但这只会锁定所有内容)
在.NET framework中是否有一种方法允许我这样做
我曾经尝试过使用EventWaitHandle(例如,在调用LongRunningTask后执行WaitOne,然后在已完成的事件中重置它,但这只会锁定所有内容)
根据定义,如果你让它同步,那将会发生什么。如果不阻塞UI线程,就无法使其同步
您需要使其阻塞,或者在回调中激发有意义的语句,而不是在操作后激发“该方法中的下一个有意义语句”
我曾经尝试过使用EventWaitHandle(例如,在调用LongRunningTask后执行WaitOne,然后在已完成的事件中重置它,但这只会锁定所有内容)
根据定义,如果你让它同步,那将会发生什么。如果不阻塞UI线程,就无法使其同步
您需要使其阻塞,或者让有意义的语句在回调中激发,而不是在操作后激发“该方法中的下一个有意义语句”。如果我阻塞UI线程,库中的BackgroundWorker将无法激发UI线程上发生的RunWorkerCompleted事件。因此,应用程序将被挂起。Background worker最初的设计思想是,它可以从UI层启动异步进程,然后在完成事件时启动。@AngryHacker:除非在此之前取消阻止,在后台线程中。@Jim:是的-在同步场景中使用BW只是在制造麻烦。如果我阻止UI线程,库中的BackgroundWorker将无法触发RunWorkerCompleted事件,该事件发生在UI线程上。因此,应用程序将被挂起。Background worker最初的设计思想是,它可以从UI层启动异步进程,然后在完成事件时启动。@AngryHacker:除非在此之前取消阻止,在后台线程中。@Jim:是的-在同步场景中使用BW只是在制造麻烦。我想看看从库中序列化回调到主线程的代码。我尝试过这样做,但失败了——在我看来,您应该为此发送更多的参数——至少是稍后用于Invoke()的控件?我想看看将回调从库序列化到主线程的代码。我尝试过做这样的事情,但失败了——在我看来,您应该为此发送更多参数——至少是稍后将用于Invoke()的控件?