c# - Thread Join() causes Task.RunSynchronously not to finish -


calling _thread.join() causes getconsumingenumerable loop stuck on last element. why behavior occur?

  public abstract class actorbase : idisposable   {     private readonly blockingcollection<task> _queue = new blockingcollection<task>(new concurrentqueue<task>());     private readonly thread _thread;     private bool _isdisposed;      protected actorbase()     {       _thread = new thread(processmessages);       _thread.start();     }      protected void queuetask(task task)     {       if (_isdisposed)       {         throw new exception("actor disposed, cannot queue task.");       }       _queue.add(task);     }      private void processmessages()     {       foreach (var task in _queue.getconsumingenumerable())       {         task.runsynchronously();       }     }      public void dispose()     {       _isdisposed = true;       _queue.completeadding();       _thread.join();     }   }    public class sampleactor : actorbase   {     private string getthreadstatus()     {       thread.sleep(500);       return string.format("running on thread {0}", thread.currentthread.managedthreadid);     }      public async task<string> getthreadstatusasync()     {       var task = new task<string>(getthreadstatus);       queuetask(task);       return await task;     }   }    class program   {     public static async task run()     {       using (var sa = new sampleactor())       {         (int = 0; < 3; i++)         {           console.writeline(await sa.getthreadstatusasync());         }       }     }      public static void main(string[] args)     {       console.writeline("main thread id {0}", thread.currentthread.managedthreadid);       var task = task.run(async ()=> { await run(); });       task.wait();     }   } 

the context approach need make sure operations executed on 1 os thread, allow part of app use different credentials main thread.

async-await works continuations. efficient , reduce scheduling these continuations run on same thread completed previous task.

that means in case special thread not running tasks, it's running continuations after these tasks (the for loop itself). can see printing thread id:

using (var sa = new sampleactor()) {     (int = 0; < 3; i++)     {         console.writeline(await sa.getthreadstatusasync());         console.writeline("continue on thread :" + thread.currentthread.managedthreadid);     } } 

when for loop completes , sampleactor being disposed call thread.join same thread trying join deadlock. situation boils down this:

public static void main() {     thread thread = null;     thread = new thread(() =>     {         thread.sleep(100);         thread.join();         console.writeline("joined");     });     thread.start(); } 

in .net 4.6 can solve taskcreationoptions.runcontinuationsasynchronously in current version can specify default taskscheduler:

public task<string> getthreadstatusasync() {     var task = new task<string>(getthreadstatus);     queuetask(task);     return task.continuewith(task1 => task1.getawaiter().getresult(), taskscheduler.default); } 

Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -