我有一个外部库,它有一个在后台线程上执行长时间运行任务的方法。完成后,它会触发启动方法的线程上的Completed事件(通常是UI线程)。它看起来像这样:
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()之后,完成事件在UI线程上5秒后触发,我更新了UI,一切都很棒,因为我不需要处理封送东西到适当的线程。
但是,我现在需要将进程同步(不更改外部库)。换句话说,在我启动.LongRunningTask方法之后,该方法中的下一个有意义的语句应该在.LongRunningTask完成之后触发。
我已尝试使用EventWaitHandle(例如在调用LongRunningTask之后执行WaitOne,然后在Completed事件中重置它,但这只是锁定所有内容)。
.NET框架中是否有允许我这样做的方法?
答案 0 :(得分:4)
我已尝试使用EventWaitHandle(例如在调用LongRunningTask之后执行WaitOne,然后在Completed事件中重置它,但这只是锁定了所有内容)。
如果按照定义进行同步,那么这正是会发生的事情。如果不阻止UI线程,就无法使其同步。
在操作之后,您不需要触发“该方法中的下一个有意义的语句”,而是需要阻止它,或者在回调中触发有意义的语句。