C# 如何等待一个BackgroundWorker完成运行另一个BackgroundWorker(C)?

C# 如何等待一个BackgroundWorker完成运行另一个BackgroundWorker(C)?,c#,backgroundworker,autoresetevent,waitone,C#,Backgroundworker,Autoresetevent,Waitone,首先,我还是一个初学者,如果您能有耐心,我将不胜感激: 我今天一直在为这事挠头 问题是,我想管理三个不同的后台工作人员。但我想等到一个完成后再运行下一个,以此类推 每个后台工作人员都需要时间来完成。长话短说,问题是,我正在使用WaitOne,所以每当前一个backgroundworker告诉我它已经完成时,我就可以开始运行新的一个,但是UI线程在三个backgroundworker完成之前是冻结的 我正在设置一个不同的AutoResetEvent,它负责整个等待和运行过程 代码如下: AutoR

首先,我还是一个初学者,如果您能有耐心,我将不胜感激:

我今天一直在为这事挠头

问题是,我想管理三个不同的后台工作人员。但我想等到一个完成后再运行下一个,以此类推

每个后台工作人员都需要时间来完成。长话短说,问题是,我正在使用WaitOne,所以每当前一个backgroundworker告诉我它已经完成时,我就可以开始运行新的一个,但是UI线程在三个backgroundworker完成之前是冻结的

我正在设置一个不同的AutoResetEvent,它负责整个等待和运行过程

代码如下:

AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
AutoResetEvent _resetHEvent = new AutoResetEvent(false);
AutoResetEvent _resetSEvent = new AutoResetEvent(false);

await Task.Run(() => bgwTestResInd.RunWorkerAsync());
_resetRIEvent.WaitOne();

await Task.Run(() => bgwTestHipot.RunWorkerAsync());
_resetHEvent.WaitOne();

await Task.Run(() => bgwTestSurge.RunWorkerAsync());
_resetSEvent.WaitOne();

MessageBox.Show("Im done for real.");
还有,允许这样做吗

private void bgwTestResInd_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetRIEvent.Set();
}


private void bgwTestHipot_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetHEvent.Set();
}


private void bgwTestSurge_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetSEvent.Set();
}

与其创建后台工作人员,然后使用任务和同步原语的人为混合在不同的时间启动工作人员,不如从头到尾使用TPL来完成整个工作:

await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());
或者,如果所有操作都是CPU限制的工作,则只需对Task进行一次调用即可。运行:

完成了


如果您确实必须使用后台工作程序,但没有真正好的理由,但无论如何,您需要做的就是在需要等待的BGW的已完成处理程序中调用RunWorkerAsync,或者,更好的是,只需要一个BGW来完成第一个BGW正在做的工作,然后再完成第二个BGW需要做的工作,然后做第三个需要做的工作。

与其创建后台工作人员,然后使用人工混合的任务和同步原语在不同的时间启动工作人员,不如从头到尾使用TPL来完成整个工作:

await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());
或者,如果所有操作都是CPU限制的工作,则只需对Task进行一次调用即可。运行:

完成了


如果您确实必须使用后台工作程序,但没有真正好的理由,但无论如何,您需要做的就是在需要等待的BGW的已完成处理程序中调用RunWorkerAsync,或者,更好的是,只需要一个BGW来完成第一个BGW正在做的工作,然后再完成第二个BGW需要做的工作,然后做第三个需要做的工作。

如果你还想坚持你的计划,这里有代码

class Program
{

    static void Main(string[] args)
    {

        var test=new Test();
        test.Run();
        Console.ReadKey();
    }

    private class Test
    {
        AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
        AutoResetEvent _resetHEvent = new AutoResetEvent(false);
        AutoResetEvent _resetSEvent = new AutoResetEvent(false);

        private BackgroundWorker bgwTestResInd = new BackgroundWorker();
        private BackgroundWorker bgwTestHipot=new BackgroundWorker();
        private BackgroundWorker bgwTestSurge=new BackgroundWorker();
        public async void Run()
        {
            bgwTestResInd.DoWork += BgwTestResInd_DoWork;
            bgwTestHipot.DoWork += BgwTestHipot_DoWork;
            bgwTestSurge.DoWork += BgwTestSurge_DoWork;

            await Task.Run(() => bgwTestResInd.RunWorkerAsync());
            _resetRIEvent.WaitOne();


            await Task.Run(() => bgwTestHipot.RunWorkerAsync());
            _resetHEvent.WaitOne();

            await Task.Run(() => bgwTestSurge.RunWorkerAsync());
            _resetSEvent.WaitOne();

            Console.Write("Done");
        }

        private void BgwTestHipot_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestHipot done..");
            _resetHEvent.Set();
        }

        private void BgwTestSurge_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestSurge done..");
            _resetSEvent.Set();
        }

        private void BgwTestResInd_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestResInd done..");
            _resetRIEvent.Set();
        }
    }
}

只需将您的代码添加到DoWork方法中,它们将按照您重置自动重置事件的顺序运行

如果您仍然想坚持您的计划,下面是代码

class Program
{

    static void Main(string[] args)
    {

        var test=new Test();
        test.Run();
        Console.ReadKey();
    }

    private class Test
    {
        AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
        AutoResetEvent _resetHEvent = new AutoResetEvent(false);
        AutoResetEvent _resetSEvent = new AutoResetEvent(false);

        private BackgroundWorker bgwTestResInd = new BackgroundWorker();
        private BackgroundWorker bgwTestHipot=new BackgroundWorker();
        private BackgroundWorker bgwTestSurge=new BackgroundWorker();
        public async void Run()
        {
            bgwTestResInd.DoWork += BgwTestResInd_DoWork;
            bgwTestHipot.DoWork += BgwTestHipot_DoWork;
            bgwTestSurge.DoWork += BgwTestSurge_DoWork;

            await Task.Run(() => bgwTestResInd.RunWorkerAsync());
            _resetRIEvent.WaitOne();


            await Task.Run(() => bgwTestHipot.RunWorkerAsync());
            _resetHEvent.WaitOne();

            await Task.Run(() => bgwTestSurge.RunWorkerAsync());
            _resetSEvent.WaitOne();

            Console.Write("Done");
        }

        private void BgwTestHipot_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestHipot done..");
            _resetHEvent.Set();
        }

        private void BgwTestSurge_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestSurge done..");
            _resetSEvent.Set();
        }

        private void BgwTestResInd_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BgwTestResInd done..");
            _resetRIEvent.Set();
        }
    }
}

只需将代码添加到DoWork方法中,它们就会按照重置AutoResetEvents的顺序运行

如果你能够使用任务,为什么还要使用BGW?我实际上是一个初学者。我真的不知道哪条路更好。如果你能使用任务,为什么还要使用BGW呢?我实际上是个初学者。我真的不知道哪条路更好。谢谢你。我还是一个初学者,所以我在选择做一些事情的方法时仍然有一些问题。谢谢你。我还是一个初学者,所以我在选择做一些事情的方式时仍然有一些问题。这不是解决问题,这是UI被阻止的问题。这不是解决问题,这是UI被阻止的问题。