Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
am using thread with BackGroundWorker by this, the application is waiting for a long time to fetch 50000 records , it make the other operation to wait until this thread complete. how can i avoid the waiting process in while using thread.

What I have tried:

C#
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 = 10000;
             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);
     }
Posted
Updated 31-Aug-16 3:31am
v3

1 solution

You're using a BackgroundWorker to push the work onto a background thread. But you're then immediately calling Dispatcher.Invoke to push the work back onto the UI thread.

As a result, you're blocking the UI thread until your work completes, and keeping a background thread idle, waiting for your UI thread to finish doing the work.

You need to move as much of the work as possible into the background thread. Remove the outer Dispatcher.Invoke call in your worker_DoWork method. When you need to update the UI, use the ReportProgress method to pass the data back to the UI thread.

Assuming it's updating the DetailReportFCBuySell property that needs to happen on the UI thread, something like this should work:
C#
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    var batchFCSB = new System.Data.DataTable();
    int row = 0;

    if (DetailReportFCBuySell.FirstOrDefault().TotalRecords > toFetchRecords)
    {
        long RecordsIcrease = 1000;
        batchFCSB = DetailReportFCBuySell.ToDataTable();
        row = 1;
        PageIndex++;
        
        for (long k = toFetchRecords; k < DetailReportFCBuySell.FirstOrDefault().TotalRecords; k = +toFetchRecords)
        {
            new AlxServiceClient().Using(channel =>
            {
                var temp = AlyexWCFService.DL.DLTTIn.FCBuySELL(transactionName, isDetails, Convert.ToDateTime(dateEdtStartDate.EditValue).Date, Convert.ToDateTime(dtpEditEndDate.EditValue).Date, Customerid, ProductID, branchID, NoOfRecords, PageIndex - 1, isBuy);
                worker.ReportProgress(0, temp);
                row++;
                PageIndex++;
            });
            
            toFetchRecords = toFetchRecords + RecordsIcrease;
        }
    }
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var temp = (ObservableCollection<dlreports.fcbuyselldetail>)e.UserState;
    DetailReportFCBuySell = DetailReportFCBuySell.Union(temp).ToObservableCollection();
}

NB: You'll need to set the worker.WorkerReportsProgress property to true, and wire up the worker_ProgressChanged method to the worker.ProgressChanged event.
 
Share this answer
 
Comments
SwethaVijayan 31-Aug-16 9:54am    
The calling thread cannot access this object because a different thread owns it.

this error found by avoid the dispacher
Richard Deeming 31-Aug-16 9:56am    
So as I said, move just the code that accesses / updates the UI to the UI thread.

If you use the dispatcher to move the entire worker_DoWork function back to the UI thread, then you might as well not bother using a BackgroundWorker in the first place.
SwethaVijayan 31-Aug-16 10:08am    
to avoid this what i should do. i need to avoid the application waing for long time. please give me a suitable answer .
Richard Deeming 31-Aug-16 10:12am    
As I keep telling you, move as much code as possible onto the background thread. Only code which accesses or updates the UI should be pushed back onto the UI thread.

I have already given you a "suitable answer"; you just need to read and understand it.
SwethaVijayan 31-Aug-16 10:38am    
i had remove the dispatcher as you said in my program an i done in another way.

private void btnExrtPDF_Click(object sender, RoutedEventArgs e)
{


if (DetailsOrSummary == "Details")
isDetails = true;
//FetchRecord();
// Task myFirstTask = Task.Factory.StartNew(FetchRecord);
lblStatus.Text = ("Progress: " + 0 + "%");
thread = new Thread(new ThreadStart(FetchRecord));

thread.Start();

}


private void FetchRecord()
{
try
{
if (Application.Current.Dispatcher.CheckAccess())
{
if (DetailsOrSummary == "Details")
isDetails = true;


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;
}
}


in this way also am getting the same error means the application waiting for a 30 sec

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900