用于多个操作的BackgroundWorker

时间:2016-05-25 08:19:12

标签: c# multithreading

我试图让我的BackgroundWorker一个接一个地顺序执行方法,但我没有运气。

我觉得值得一提的是,我是一名专业的SQL开发人员,而且我正在拓展我的开发范围。我认为没有坏处:)

我意识到我可以为我已经开始的操作数量生成新线程但是我想在BackgroundWorker上执行的操作在SQL Server中执行存储过程,因此在多个线程上同时运行多个查询,而数百人是在服务器上工作并不理想,因为我在ETL表中存储了大量数据。

基本上我现在拥有以下内容:

internal async void MethodA(DateTime startDate, DateTime endDate)
    {
        // Execute Stored Procedure which populates an ETL Table
        // I use a SQLCommand object and call it using
        // await sqlCommand.ExecuteNonQueryAsync();
    }

internal async void MethodB(DateTime startDate, DateTime endDate)
    {
        // Execute Stored Procedure which populates another ETL Table
        // I use a SQLCommand object and call it using
        // await sqlCommand.ExecuteNonQueryAsync();
    }

我想像这样一个接一个地调用这些方法:

private void btnCreateFile_Click(object sender, EventArgs e)
    {
        ProcessMethodA();
        ProcessMethodB();
    }


void ProcessMethodA()
    {
        if (!backgroundWorker1.IsBusy)
        {
            Cursor = Cursors.WaitCursor;
            dtLossRatio.Clear();
            lblProgress.Visible = true;
            lblProgress.Text = "Building ETL A...";
            pbProcessWait.Visible = true;
            pbProcessWait.Location = new Point(420, 413);
            process = "ProcessA";
            backgroundWorker1.RunWorkerAsync();
        }
    }


void ProcessMethodB()
    {
        if (!backgroundWorker1.IsBusy)
        {
            Cursor = Cursors.WaitCursor;
            dtLossRatio.Clear();
            lblProgress.Visible = true;
            lblProgress.Text = "Building ETL B...";
            pbProcessWait.Visible = true;
            pbProcessWait.Location = new Point(456, 413);
            process = "ProcessB";
            backgroundWorker1.RunWorkerAsync();
        }
    }

对于我的BackgroundWorker,我有这个:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        switch (process)
        {
            case "ProcessA":
                logic.MethodA(DateTimePicker1.Value, DateTimePicker2.Value);
                break;
            case "ProcessB":
                logic.MethodB(DateTimePicker3.Value, DateTimePicker4.Value);
                break;
        }
    }

我感觉这些过程变化应该在

中改变
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    }

我不知道该怎么做。

我尝试过使用任务,但我不知道如何报告完成一项任务以便代码开始执行新操作:

Task ExecuteProcessA()
    {
        Action invoker = new Action(ProcessA);
        return Task.Run(invoker);
    }

任何帮助都会很棒!

1 个答案:

答案 0 :(得分:2)

  

我觉得值得一提的是,我是一名专业的SQL开发人员,而且我正在拓展我的开发范围。

我建议您阅读我的async introasync best practices条款。我还有why you should replace BackgroundWorker with Task.Run的整个系列。

  

同时在多个线程上运行多个查询,而数百人在服务器上工作并不理想

绝对正确,很多.NET开发人员都没有想到。 :)

  

基本上我现在拥有以下内容:

我的article on async best practices的主要教训之一是“避免async void”。 async void不自然;没有返回值的async方法的正确返回类型是Task,而不是void。在某些情况下,您使用async void(最明显的是异步事件处理程序),但除非 使用{{}},否则您应该使用Task {1}}。

所以,如果我们只是改变那些方法来代替void

Task

则...

  

我想一个接一个地调用这些方法

实际上非常简单:

internal async Task MethodAAsync(DateTime startDate, DateTime endDate)
internal async Task MethodBAsync(DateTime startDate, DateTime endDate)

事实上,我认为您根本不需要await MethodAAsync(startDate, endDate); await MethodBAsync(startDate, endDate); (或Task.Run):

BackgroundWorker