1

首先,我还是一个初学者,所以如果你能有一些耐心,我将不胜感激:)

今天我一直在为此苦苦思索。

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

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

我正在设置一个不同的 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();
}
4

2 回答 2

5

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

await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());

或者,如果所有操作都是 CPU 密集型工作,您可以简单地使用一次调用Task.Run

await Task.Run(() =>
{
    TheWorkThatTheFirstBGWWasDoing());
    TheWorkThatTheSecondBGWWasDoing());
    TheWorkThatTheThirdBGWWasDoing());
});

完毕。

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

于 2017-01-17T22:37:11.343 回答
-1

如果你仍然想坚持你的计划,这里是代码

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 的顺序运行

于 2017-01-17T22:59:10.147 回答