c# - ShowDialog and UI interaction in BackGroundWorker Thread -
after 2 hours of researching, still couldn't find solution problem.
the task process files in backgroundworker thread. however, need use showdialog let user choose savefile location i'm getting sta/mta error.
mainform code:
private void button2_click(object sender, eventargs e) { button1.enabled = false; processreportworker.runworkerasync(); }
dowork code:
void processreportworker_dowork(object sender, doworkeventargs e) { int reportcount = reports.count(); foreach (string report in reports) { processreport newreport = new processreport(report); string result = newreport.start(); } }
processreport.start() code:
class processreport { public string start() { if(file.exists(resultpath)) { savefiledialog savereport = new savefiledialog(); savereport.initialdirectory = "c:\somepath"; savereport.checkpathexists = true; savereport.defaultext = ".xls"; savereport.overwriteprompt = true; savereport.validatenames = true; if (savereport.showdialog() == dialogresult.ok) { resultpath = savereport.filename; if (file.exists(resultpath)) file.delete(resultpath); } } } }
as can see, showdialog needed in cases. believe can done using delegates i'm not familiar delegates. did try solution jon in calling showdialog in backgroundworker couldn't work. (maybe i'm doing wrong delegates?)
someone please me this. please provide me code delegates if needed this. thanks!
edit: solution given poweredbyorange worked. however, had make small change it:
this.invoke((methodinvoker)delegate{....}); did not work because - intention refer mainform instance code exists in processreport class. "this" here referring processreport class instance, must refer gui instance (mainform instance) work.
my fix: sent instance of mainform processreport class , made changes mentioned below:
in dowork:
processreport newreport = new processreport(report, this); //change: sending 'this' //this sends reference of mainform(gui) processreport class
in processreport class:
class processreport { mainform mainforminstance; public processreport(string report, mainform x) { mainforminstance = x; } public string start() { mainforminstance.invoke((methodinvoker)delegate //changed this.invoke mainforminstance.invoke { savefiledialog savereport = new savefiledialog(); savereport.initialdirectory = "c:\somepath"; savereport.checkpathexists = true; savereport.defaultext = ".xls"; savereport.overwriteprompt = true; savereport.validatenames = true; if (savereport.showdialog() == dialogresult.ok) { resultpath = savereport.filename; if (file.exists(resultpath)) file.delete(resultpath); } }); } }
so above thing worked. understood pretty well, poweredbyorange.
the reason you're getting exception because thread owns control allowed modify/access it. in case, savefiledialog
belongs main thread, start()
method running in different (i.e. background) thread. therefore, background thread in case needs ask main thread open savefiledialog.
public string start() { if(file.exists(resultpath)) { this.invoke((methodinvoker)delegate { savefiledialog savereport = new savefiledialog(); savereport.initialdirectory = "c:\somepath"; savereport.checkpathexists = true; savereport.defaultext = ".xls"; savereport.overwriteprompt = true; savereport.validatenames = true; if (savereport.showdialog() == dialogresult.ok) { resultpath = savereport.filename; if (file.exists(resultpath)) file.delete(resultpath); } }); } }
to make more clear, assume want friend give 1 of his textbooks. not allowed go friend's room , steal book. do, call friend (invoke) , ask favor (delegate).
Comments
Post a Comment