.net - How to wait for tasks to finish without blocking the UI -


this first question in forum , since i'm not native english speaker hope you'll go easy on me, in case i'm doing or saying wrong.

so, here question:

i solve simple problem (so seems), i'm researching on week , tried different things none of worked far, stumbled on same problem.

what opening progress form, starting 2 long running tasks (for instance getting data 2 databases). these long running tasks report progress progress form, after they're finished progress form closes , form opens show results of 2 long running tasks. both tasks have complete (or cancel/fail) before progress form closes , program goes on (or closes).

so, progress form (form1) contains 2 listboxes (listbox1 , listbox2) , following code:

public delegate sub showprogressdelegate(byval message string)  public class form1  public sub addmessage1(byval message string)   if string.isnullorempty(message)     exit sub   end if    if me.invokerequired     me.invoke(new showprogressdelegate(addressof me.addmessage1), new object() {message})   else     me.listbox1.items.add(message)     me.listbox1.selectedindex = me.listbox1.items.count - 1     application.doevents()   end if end sub  public sub addmessage2(byval message string)   if string.isnullorempty(message)     exit sub   end if    if me.invokerequired     me.invoke(new showprogressdelegate(addressof me.addmessage2), new object() {message})   else     me.listbox2.items.add(message)     me.listbox2.selectedindex = me.listbox2.items.count - 1     application.doevents()   end if end sub  end class 

then have testclass simulates long running tasks , raises progress events:

imports system.threading  public class testclass    public event showprogress(byval message string)    private _milliseconds ushort    public sub new(milliseconds ushort)     _milliseconds = milliseconds   end sub    public function run() ushort     integer = 1 20       raiseevent showprogress("run " & i)       thread.sleep(_milliseconds)     next      return _milliseconds   end function  end class 

and have main procedure tries put these 2 together:

imports system.threading.tasks imports system.componentmodel  public class start   private const multi_thread boolean = true    public shared sub main()     dim testclass(1) testclass     dim testtask(1) task(of ushort)     dim result(1) ushort      testclass(0) = new testclass(50)     testclass(1) = new testclass(100)      using frm form1 = new form1       frm.show()        addhandler testclass(0).showprogress, addressof frm.addmessage1       addhandler testclass(1).showprogress, addressof frm.addmessage2        if multi_thread         testtask(0) = task(of ushort).factory.startnew(function() testclass(0).run)         testtask(1) = task(of ushort).factory.startnew(function() testclass(1).run)          task.waitall(testtask(0), testtask(1))          result(0) = testtask(0).result         result(1) = testtask(1).result       else         result(0) = testclass(0).run         result(1) = testclass(1).run       end if        removehandler testclass(0).showprogress, addressof frm.addmessage1       removehandler testclass(1).showprogress, addressof frm.addmessage2        frm.close()     end using      messagebox.show("result 1: " & result(0) & "; result 2: " & result(1))   end sub  end class 

if set constant multi_thread false, works fine (but sequentially). if set if true, shows form, no progress , never shows resulting message box either. if debug never reaches line after task.waitall(...).

i tried other approaches multi threading working plain threads (no return values), backgroundworkers (only percentage progress, no text messages), begininvoke/endinvoke on delegates, nothing worked or showed same behaviour described above.

i told in forum, task.waitall blocks ui-thread since called on ui-thread, can't believe since msdn states task.waitall waits handed-over tasks finish or fail , didn't hand on ui thread.

so, don't know else try, hope can point out mistake me or show me way try solve little problem.

thank in advance.

update:
did little bit more testing , debugging. if change 2 "me.invoke(...)" in code of form "me.begininvoke(...)" still no progress messages shown in form, @ least tasks work , closing message box. actual delivering or showing of progress messages seems cause problem.

maybe triggers in minds?

thank again.

update ii:
after lot of trial , error seems work, @ least little bit. instead of "me.invokerequired" parts in code of form handed on "taskscheduler.fromcurrentsynchronizationcontext" when creating tasks. @ least got progress messages shown, tasks still don't run parallel. that's topic next question here.

you process might taking of resources available @ system side. starting new task, try starting complete new thread heavy processes

you can start progress ui in separate thread wont stop responding

thread nthread; private void button1_click(system.object sender, system.eventargs e) {     nthread = new thread(showdlg);     nthread.start(); }  private void showdlg() {     form1 nwin = new form1();     nwin.showdialog(); } 

Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -