多线程使应用程序等待很长时间?

时间:2016-08-31 13:13:48

标签: c# multithreading

我需要从数据库中获取1000000条记录,因此我一次在循环1000条记录中获取记录并与主集合联合。一次在1000条记录的切片中获取1000000条记录需要很长时间。在此期间,我需要在应用程序中执行另一项工作,但我的应用程序正在等待所有这些时间(超过1分钟)。

请你给我一个暗示我可以做些什么来接受主线程的工作?

 private void btnExrtPDF_Click(object sender, RoutedEventArgs e)
    {
        if (DetailsOrSummary == "Details")
            isDetails = true;  
        thread = new Thread(new ThreadStart(FetchRecord));
        thread.Start();
    }
 private void FetchRecord()
    {
        try
        {
            if (Application.Current.Dispatcher.CheckAccess())
            {
                if (DetailsOrSummary == "Details")
                    isDetails = true;

                long NoOfRecords = 1000;
                long toFetchRecords = 1000;
                DetailReportFCBuySell = AlyexWCFService.DL.DLTTIn.FCBuySELL(transactionName, isDetails, Convert.ToDateTime(dateEdtStartDate.EditValue).Date, Convert.ToDateTime(dtpEditEndDate.EditValue).Date, Customerid, ProductID, branchID, NoOfRecords, PageIndex - 1, isBuy);
                long RecordsIcrease = 1000;
                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();
                        PageIndex++;
                    });
                    toFetchRecords = toFetchRecords + RecordsIcrease;
                }

                ResultsData = DetailReportFCBuySell.ToDataTable();// (Collection.Where(i => i.Key == k).FirstOrDefault().Value);
                ExportToOxml(true);
            }
            else
            {
                //Other wise re-invoke the method with UI thread access
                Application.Current.Dispatcher.Invoke(new System.Action(() => FetchRecord()));
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

1 个答案:

答案 0 :(得分:4)

在工作线程中,您正在检查您是否在UI线程中,否则您使用调度程序在UI线程中执行该方法。所以从UI线程开始一个工作线程来执行一些工作,它检查它是否在UI线程中,如果没有,则在UI线程上调用自己。

正是这种模式:

private void FetchRecord()
{
    // try omitted...
    if (Application.Current.Dispatcher.CheckAccess())
    {
        // do work...
    }
    else
    {
        Application.Current.Dispatcher.Invoke(new System.Action(() => FetchRecord()));
    }
}

对我来说似乎不合逻辑。

我认为解决方案不是检查Dispatcher。你为什么这样做?

另一个观察结果:如果您不想添加任何内容,请删除try-catch。事实上,这是无用的。

从聊天更新:

您需要将非UI逻辑与UI逻辑分开。在这种情况下,您需要创建一些字段来存储UI值,您可以在工作线程中使用它们。像这样:

私人字段:

private DateTime _editStartDate; 
private DateTime _editEndDate; 

在启动工作线程之前设置它们:

_editStartDate = Convert.ToDateTime(dateEdtStartDate.EditValue).Date; 
_editEndDate = Convert.ToDateTime(dtpEditEndDate.EditValue).Date; 
// now start the thread 

并在工作线程中运行的方法中使用它们。

DetailReportFCBuySell = AlyexWCFService.DL.DLTTIn.FCBuySELL(
    transactionName, 
    isDetails, 
    _editStartDate, // use the field
    _editEndDate,   // use the field
    Customerid, 
    ProductID, 
    branchID, 
    NoOfRecords, 
    PageIndex - 1, 
    isBuy
);