我正在使用带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);
}
答案 0 :(得分:1)
您的代码完全错误。您不应该同时拨打Dispatcher.BeginInvoke()
或Dispatcher.Invoke()
。对BeginInvoke()
的调用毫无意义,没有任何用处,后者导致所有工作都在UI线程中完成,而不是在它所属的后台工作线程中完成。
您可以使用更多现代方法而不是BackgroundWorker
,例如await Task.Run(...)
。没有好的Minimal, Complete, and Verifiable code example,就不可能提出更具体的建议。但是,由于您发布的代码现在已经存在,如果您只是删除对Dispatcher
方法的所有调用并直接执行调用的代码,它应该按预期工作。
答案 1 :(得分:-1)
这就是你如何使用后台工作者。
将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");
}
}