c# - Task synchronization without a UI thread -


in code below want syncronize reporting of results of list of tasks. working because task.result blocks until task completes. however, task id = 3 takes long time complete , blocks of other finished tasks reporting status.

i think can moving reporting (console.write) .continuewith instruction don't have ui thread how taskscheduler syncronize .continuewith tasks?

what have now:

static void main(string[] args) {     console.writeline("starting on {0}", thread.currentthread.managedthreadid);      var tasks = new list<task<int>>();      (var = 0; < 10; i++)     {         var num = i;         var t = task<int>.factory.startnew(() =>         {            if (num == 3)            {                thread.sleep(20000);            }            thread.sleep(new random(num).next(1000, 5000));            console.writeline("done {0} on {1}", num, thread.currentthread.managedthreadid);            return num;         });         tasks.add(t);     }      foreach (var task in tasks)     {         console.writeline("completed {0} on {1}", task.result, thread.currentthread.managedthreadid);     }      console.writeline("end of main");     console.readkey(); } 

i move or similar need console.write("completed...") happen on same thread:

static void main(string[] args) {     console.writeline("starting on {0}", thread.currentthread.managedthreadid);      (var = 0; < 10; i++)     {         var num = i;         task<int>.factory.startnew(() =>         {            if (num == 3)            {                thread.sleep(20000);            }            thread.sleep(new random(num).next(1000, 10000));            console.writeline("done {0} on {1}", num, thread.currentthread.managedthreadid);            return num;        }).continuewith(value =>        {            console.writeline("completed {0} on {1}", value.result, thread.currentthread.managedthreadid);        }        /* need syncronization context */);     }      console.writeline("end of main");     console.readkey(); } 

-- solution -- after getting comments , reading of solutions complete solution want. goal here process severl long running tasks fast possible , results of each task 1 @ time.

static void main(string[] args) {     console.writeline("starting on {0}", thread.currentthread.managedthreadid);      var results = new blockingcollection<int>();      task.factory.startnew(() =>     {         while (!results.iscompleted)         {             try             {                 var x = results.take();                 console.writeline("completed {0} on {1}", x, thread.currentthread.managedthreadid);             }             catch (invalidoperationexception)             {             }         }         console.writeline("\r\nno more items take.");     });      var tasks = new list<task>();      (var = 0; < 10; i++)     {         var num = i;         var t = task.factory.startnew(() =>         {             if (num == 3)             {                 thread.sleep(20000);             }             thread.sleep(new random(num).next(1000, 10000));             console.writeline("done {0} on {1}", num, thread.currentthread.managedthreadid);             results.add(num);         });          tasks.add(t);     }      task.factory.continuewhenall(tasks.toarray(), _ => results.completeadding());      console.writeline("end of main");     console.readkey(); } 

you'll have create writer task of sort, however, keep in mind this task can rescheduled onto native or managed thread! using default scheduler in tpl have no control on managed thread receives work.

public class concurrentconsole {     private static blockingcollection<string> output         = new blockingcollection<string>();      public static task createwritertask(cancellationtoken token)     {         return new task(             () =>             {                 while (!token.iscancellationrequested)                 {                     string nextline = output.take(token);                     console.writeline(nextline);                 }             },             token);     }      public static void writeline(func<string> writeline)     {         output.add(writeline());     } } 

when switched code use received following output:

end of main done 1 on 6 completed 1 on 6 done 5 on 9 completed 5 on 9 done 0 on 4 completed 0 on 4 done 2 on 5 completed 2 on 13 done 7 on 10 completed 7 on 10 done 4 on 8 completed 4 on 5 done 9 on 12 completed 9 on 9 done 6 on 6 completed 6 on 5 done 8 on 11 completed 8 on 4 done 3 on 7 completed 3 on 7 

even code sending () => string.format("completed {0} on {1}"... concurrentconsole.writeline, ensuring managedthreadid picked on concurrentconsole task, still alter thread ran on. although less variability executing tasks.


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -