Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
I have windows application in which i need to save data into database and after saving data load crystal report to show report,all this happens on click of save button.
 
I have button named btn_Submit on click of this data is saved and display report, while saving it takes time so i want to show progress bar for mean time so that user get known that data is in process
i was able to save data into db using but when displaying Report named SalesReport i got the error saying
Cross-thread operation not valid: Control 'frmParent' accessed from a thread other than the thread it was created on.
on the line sreport .MdiParent = arg.parentf; in following code.
 
frmparent is MDI form. is there any solution?
 

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
    PrintData arg = (PrintData)e.Argument;
               SalesMaster sm = arg.SalesData;
               BrokerMaster bm = arg.Broker;
               CustomerMaster ctm = arg.Customer;
               CompanyMaster cm = arg.Company;
               ArrayList hb = arg.Arrardata;
               int totunit = arg.totunit;
               decimal globalamt = arg.golbamt;
               SalesReport sreport = new SalesReport(sm, ctm, cm, bm, hb, totunit, glb_totalamt);
 

               sreport .MdiParent = arg.parentf;
 

               sreport .WindowState = FormWindowState.Maximized;
               sreport .Show();
}
Posted 27-Nov-12 3:33am
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You cannot interact with UI items from a background thread. ALL access to ANY UI items must be done on the UI thread (the thread your app started on).
 
All of the code after and including the SalesReport sreport..." line MUST be run on the UI thread, not in the BackgroundWorker.
 
Judging by the content of this code block, there's no reason for the remaining code to be run on a BackgroundWorker, so you really don't need a background thread for this code.
  Permalink  
Comments
sharadpanwal at 27-Nov-12 8:49am
   
all my code including save and show report,are time consuming so i just added code to background worker to show loading bar.is there any other way?
Collin Jasnoch at 27-Nov-12 8:58am
   
Then that time consuming code should be on the background worker. There is no need to have UI construction on a background worker (nor is it possible). You may need to refactor what is going on in the SalesReport construction and execute the refactored code using BW, and then have callbacks create the UI.
Dave Kreskowiak at 27-Nov-12 9:59am
   
Assuming that the "SalesReport" method only does processing to generate the data for a report, you farm just that work to a background worker, NOT the code that touches the UI controls and actually shows the report. That code can run when the background worker raises its RunWorkerCompleted event.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

You can not access Windows UI components from a thread that did not create it (as the error states).
 
The solution is to use a delegate to get back to the UI thread or use the Progress update or complete event. I recommend the last one for you case as it seems you are done with the worker thread.
Updating progress is more for long running process that you want feedback (i.e. progress bar). Using a delegate is necessary in some cases but this is not one of them.
 
Here is how you use the Progress change event and/or the completion event (you should use the completion event and put the "SalesReport" code there)
 
BackgroundWorker worker = new BackgroundWorker();
 
worker.ProgressChanged += worker_ProgressChanged;
worker.WorkerReportsProgress = true; //You need to set this if you require updates or you will get an exception
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
 
...
 
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//This is called after the DoWork method completes
   throw new NotImplementedException();
}
 
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //This is called anytime the worker thread calls "ReportProgress". Note you must have set WokerReportsProgress to true
    throw new NotImplementedException();
}
  Permalink  
v3

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

  Print Answers RSS
0 Maciej Los 230
1 OriginalGriff 202
2 Richard MacCutchan 185
3 Tomas Takac 146
4 CPallini 125
0 OriginalGriff 5,130
1 DamithSL 4,237
2 Maciej Los 3,700
3 Kornfeld Eliyahu Peter 3,470
4 Sergey Alexandrovich Kryukov 2,846


Advertise | Privacy | Mobile
Web01 | 2.8.141216.1 | Last Updated 27 Nov 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100