c# - task deadlock when invoking in worker threads -


i have windows form program (**vs 2010 .net 4 **) detecting recursively folders , sub folders of directory , optimizing files. tasking library , have progressbar shows progress of item , label near progressbar shows current file. have settext(string text) method , delegate (delegate void settextcallback(string text);) use purpose. when want show messagebox @ end of process think deadlock. when don't use task.wait(); in button6_click goes ok , ui won't hang. code:

    public partial class form1 : form     {   int maxfilecounter = 0;     static int filecounter = 0;  delegate void settextcallback(string text); delegate void setprogresscallback(int i);  private void button6_click(object sender, eventargs e) {     task task = task.factory.startnew(() =>     {         editfiles(txtfilepath.text);     });      task.wait();      messagebox.show("finished"); }  private void editfiles(string directorypath) {     try     {         //directoryinfo dirinfo = new directoryinfo(txtfilepath.text);         directoryinfo dirinfo = new directoryinfo(directorypath);         //string[] extensionarray = { ".jpg", ".png", ".gif" ,".jpeg"};         string[] extensionarray = txtextensionlist.text.split(';');         hashset<string> allowedextensions = new hashset<string>(extensionarray, stringcomparer.ordinalignorecase);          fileinfo[] files = array.findall(dirinfo.getfiles(), f => allowedextensions.contains(f.extension));         writefiles(files);          foreach (directoryinfo dir in dirinfo.getdirectories())         {             editfiles(dir.fullname);         }     }     catch (exception ex)     {         messagebox.show(ex.message);     } }  private void writefiles(fileinfo[] files) {     try     {         foreach (fileinfo fileinfo in files)         {             memorystream mo;              using (image image = image.fromfile(fileinfo.fullname))             {                  settext(fileinfo.fullname);                  filecounter++;                  setprogress(filecounter * 100 / maxfilecounter);                  mo = (memorystream)optimizeimage(image, int.parse(txtpercent.text));             }              byte[] bt = new byte[mo.length];             mo.read(bt, 0, bt.length);             mo.flush();             mo.close();              string fullpath = fileinfo.fullname;              file.writeallbytes(fullpath, bt);          }     }     catch (exception ex)     {         messagebox.show(ex.message);     } }  private void settext(string text) {     // invokerequired required compares thread id of     // calling thread thread id of creating thread.     // if these threads different, returns true.     if (lblfilename.invokerequired)     {         settextcallback d = new settextcallback(settext);         this.invoke(d, new object[] { text });     }     else     {         this.lblfilename.text = text;     } } private void setprogress(int i) {     if (progressbar1.invokerequired)     {         setprogresscallback p = new setprogresscallback(setprogress);         this.invoke(p, new object[] { });     }     else     {         this.progressbar1.value = i;     } } } 

how can handle it?

    this.invoke(d, new object[] { text }); 

the point of using task not wait it. if anyway you'll hang ui thread. goes catatonic, no longer being responsive notifications windows. including ones own code generates, invoke() call does. sends message ui thread go delegate invoke.

so invoke() call cannot complete, ui thread hung. task.wait() call cannot complete since task hung on invoke() call. deadly embrace, 1 of standard threading bugs called deadlock.

note how begininvoke() doesn't have problem, doesn't wait completion. solves deadlock, doesn't provide live update since still have ui thread that's dead world. must remove wait() call. can messagebox.show() call run adding task continuation taskscheduler.fromcurrentsynchronizationcontext(). , need fret getting task stop when user closes window, letting continue running not (in general) turn out well. async/await keywords added c# version 5 more general solution problem.


Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -