与BackgroudWorker的线程,等待很长时间。我怎么能避免这种情况

时间:2016-08-31 06:54:22

标签: c# multithreading c#-4.0 backgroundworker

我正在使用带BackgroundWorker的线程,应用程序等待很长时间才能获取50000条记录,这使得另一条操作等待此线程完成。如何在使用辅助线程时避免等待过程。

private void btnExrtPDF_Click(object sender, RoutedEventArgs e)
{
    if (DetailsOrSummary == "Details")
        isDetails = true;

    Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
    {
        try
        {
            DetailReportFCBuySell = AlyexWCFService.DL.DLTTIn.FCBuySELL(
                transactionName, isDetails,
                Convert.ToDateTime(dateEdtStartDate.EditValue).Date,
                Convert.ToDateTime(dtpEditEndDate.EditValue).Date,
                Customerid, ProductID, branchID,
                NoOfRecords, PageIndex - 1, isBuy);

            worker.RunWorkerAsync();
        }
        catch
        {            
            object obj = new object(); 
        }
    }));
}

private void worker_DoWork(object sender, DoWorkEventArgs e)
{        
    Dispatcher.Invoke(new Action(() =>
    {
        System.Data.DataTable batchFCSB = new System.Data.DataTable();
        int row = 0;

        if (DetailReportFCBuySell.FirstOrDefault().TotalRecords > toFetchRecords)
        {
            long RecordsIcrease = 1000;
            batchFCSB = DetailReportFCBuySell.ToDataTable();
            //Collection.Add(row, batchFCSB);
            row = 1;
            PageIndex++;

            for (long k = toFetchRecords; k < DetailReportFCBuySell.FirstOrDefault().TotalRecords; k = +toFetchRecords)
            {
                new AlxServiceClient().Using(channel =>
                {
                    ObservableCollection<DLReports.FCBuySellDetail> temp
                        = AlyexWCFService.DL.DLTTIn.FCBuySELL(
                            transactionName, isDetails,
                            Convert.ToDateTime(dateEdtStartDate.EditValue).Date,
                            Convert.ToDateTime(dtpEditEndDate.EditValue).Date,
                            Customerid, ProductID, branchID, NoOfRecords, PageIndex - 1, isBuy);

                    DetailReportFCBuySell = DetailReportFCBuySell.Union(temp).ToObservableCollection();

                    row++;
                    PageIndex++;

                });
                toFetchRecords = toFetchRecords + RecordsIcrease;
            }
        }
    }), DispatcherPriority.ContextIdle);
}

2 个答案:

答案 0 :(得分:1)

您的代码完全错误。您不应该同时拨打Dispatcher.BeginInvoke()Dispatcher.Invoke()。对BeginInvoke()的调用毫无意义,没有任何用处,后者导致所有工作都在UI线程中完成,而不是在它所属的后台工作线程中完成。

您可以使用更多现代方法而不是BackgroundWorker,例如await Task.Run(...)。没有好的Minimal, Complete, and Verifiable code example,就不可能提出更具体的建议。但是,由于您发布的代码现在已经存在,如果您只是删除对Dispatcher方法的所有调用并直接执行调用的代码,它应该按预期工作。

答案 1 :(得分:-1)

这就是你如何使用后台工作者。

Sample app

将2个按钮添加到WinForm。

首先,btnStartWorker会触发后台工作程序。

虽然禁用了btnStartWorker并且后台工作程序正在运行,但仍然可以单击btnOther。

public partial class Form1 : Form
{
    private delegate void ReenableDelegate();

    public Form1()
    {
        InitializeComponent();
    }

    private BackgroundWorker worker;
    private void btnStartWorker_Click(object sender, EventArgs e)
    {
        btnStartWorker.Enabled = false;

        worker = new BackgroundWorker();
        worker.DoWork += Worker_DoWork;
        worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
    }

    private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {

        Thread.Sleep(5000); // simulate long running operation here
    }

    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.Invoke(new ReenableDelegate(Enable));
    }

    private void Enable()
    {
        btnStartWorker.Enabled = true;
    }

    private void btnOther_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Doing other stuff");
    }
}