代码之家  ›  专栏  ›  技术社区  ›  AngryHacker

如何防止在后台任务完成之前向前移动?

  •  0
  • AngryHacker  · 技术社区  · 14 年前

    我有一个外部库,它有一个在后台线程上执行长时间运行任务的方法。完成后,它会在启动方法的线程(通常是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,然后在完成的事件中重置它,但这会锁定所有内容)。

    .NET框架中是否有允许我执行此操作的方法?

    1 回复  |  直到 14 年前
        1
  •  4
  •   Reed Copsey    14 年前

    我尝试过使用EventWaitHandle来完成它(例如,在调用LongRunningTask之后执行WaitOne,然后在完成的事件中重置它,但这会锁定所有内容)。

    根据定义,如果您将此同步化,则会发生这种情况。如果不阻塞UI线程,就无法使其同步。