c# - CrossThreading issue with BackgroundWorker and statusstrip update -


i have been working on tool uses backgroundworker perform ping operation on regular interval. running issue backgroundworker progresschanged event. code progresschanged event below:

private void backgroundworker1_progresschanged(object sender, progresschangedeventargs e)        {            progressupdated update = (progressupdated)e.userstate;            if (sender.tostring() == "system.componentmodel.backgroundworker")            {                toolstripstatuslabel1.text = update.generalstatus;                toolstripprogressbar1.value = update.progressstatus;                toolstripstatuslabel2.text = update.specificstatus;            }            else            {                toolstripstatuslabel1.text = update.generalstatus;                toolstripprogressbar2.value = update.progressstatus;                toolstripstatuslabel3.text = update.specificstatus;            }        } 

the progresschanged event gets called both in backgroundwork updates first values , pingcompletedcallback event when ping finishes. run cross threading issue when progresschanged event runs pingcompletedcallback event. throws error when goes update second progress bar.

i can not seem figure out why happening 1 of calls not other.

is pingcompletedcallback happening on backgroundworker thread , thats why causing cross threading issues?

if how raise event processed on ui thread , not backgroundworker?

edit:

private void backgroundworker1_dowork(object sender, doworkeventargs e)     {          backgroundworker worker = sender backgroundworker;          // creates ping , sends async          progressupdated args = new progressupdated(string1, int1, string 2);          worker.reportprogress(0,args);          // rest of thread cleanup when cancellation called     } private void pingcompletedcallback(object sender, pingcompletedeventargs e)     {             // handle ping response             progressupdated update = new progressupdated(string1, int1, string2);             progresschangedeventargs changed = new progresschangedeventargs(1,update);             backgroundworker1_progresschanged(this, changed);             // handle other types of responses      } 

i thought use of events allow separation of threads. aka worker thread raises event ui thread listening for, raised event gets processed on ui thread.

since understanding wrong, pingcompletedcallback have access the reportprogress method of backgroundworker?

i change in pingcompletedcallback:

progresschangedeventargs changed = new progresschangedeventargs(1,update); backgroundworker1_progresschanged(this, changed); 

to:

backgroundworker1.reportprogress(1, update); 

or need change in other way?

thanks anyone's assistance.

edit 2:

changed progrsschanged event

private void backgroundworker1_progresschanged(object sender, progresschangedeventargs e)        {            progressupdated update = (progressupdated)e.userstate;            toolstripstatuslabel1.text = update.generalstatus;            toolstripprogressbar1.value = update.progressstatus;            toolstripstatuslabel2.text = update.specificstatus;        } 

i created second update event

private void pingupdate (object sender, progressupdated e)     {          toolstripstatuslabel1.text = e.generalstatus;          toolstripprogressbar2.value = e.progressstatus;          toolstripstatuslable3.text = e.sepcificstatus;     } 

the thing have left call new event pingcompletedcallback in such way gets executed on ui thread. invoke statement used or should invokes used in new event?

the documentation backgroundworker states should not manipulating ui objects through dowork method, , changes ui objects should made through reportprogress. haven't looked @ reflector, it's performing hidden "invoke" you. whatever raising pingcompleted event executing within worker thread or other thread not main thread.

you see in threads window of visual studio debugger dotask not execute on main thread; however, when reportprogress called, handler executed on main thread. since controls created on main thread, not see exception. enter image description here

now, if attempt call backgroundworker1_progresschanged explicitly within dowork method, backgroundworker1_progressedchanged executed on same thread that's executing dowork method, or, in case, method that's raising pingcompleted event: enter image description here

you can solve cross thread exception adding invokerequired checks within backgroundworker1_progresschanged handler, or route pingcompleted handler call reportprogress

edit:

calling reportprogress pingcompleted handler won't work because lose original sender.

private void backgroundworker1_progresschanged(object sender, progresschangedeventargs e) {     if (invokerequired)     {         invoke(new progresschangedeventhandler(backgroundworker1_progresschanged), sender, e);         return;     }      // rest of code goes here } 

edit 2 response:

private void pingupdate (object sender, progressupdated e) {      if (invokerequired)      {         invoke(new action<object, progressupdated>(pingupdate), sender, e);         return;      }       toolstripstatuslabel1.text = e.generalstatus;      toolstripprogressbar2.value = e.progressstatus;      toolstripstatuslable3.text = e.sepcificstatus; } 

Comments

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -