C# Task - Linked cancellation token not working -


please if me. i'm trying use tpl linked cancellation tokens. issue after cancellation of main cancellationtokensource, value of linked token's property iscancellationrequested still "false".

i'm starting 2 tasks, sure - should same thing. first pass cancellationtoken, , second pass cancellationtokensource. behaviour same: in while loops - condition linkedtoken.iscancellationrequested stays "false" after cancellation.

here code using:

public class manager {     private task tokentask;     private task sourcetask;     private cancellationtokensource maincancelationtokensource;     private cancellationtoken maintoken;      public manager()     {         this.maincancelationtokensource = new cancellationtokensource();         this.maintoken = maincancelationtokensource.token;         this.maintoken.register(maincanceled);     }      public void start()     {         workers w = new workers();         tokentask = task.run(() => w.doworktoken(maintoken), maintoken);         sourcetask = task.run(() => w.doworksource(maincancelationtokensource), maincancelationtokensource.token);      }     public void cancel()     {         maincancelationtokensource.cancel();     }      private void maincanceled()     {         try         {             tokentask.wait();         }         catch (exception e)         {          }          try         {             sourcetask.wait();         }         catch (exception e)         {          }     } }  class workers {     public void doworktoken(cancellationtoken maintoken)     {         cancellationtokensource linkedcts = cancellationtokensource.createlinkedtokensource(maintoken);         cancellationtoken linkedtoken = linkedcts.token;          while (!linkedtoken.iscancellationrequested)         {             random r = new random();             task.delay(200 * r.next(1, 11)).wait();         }          linkedtoken.throwifcancellationrequested();     }      public void doworksource(cancellationtokensource maincts)     {         cancellationtokensource linkedcts = cancellationtokensource.createlinkedtokensource(maincts.token);          while (!linkedcts.token.iscancellationrequested)         {             random r = new random();             task.delay(200 * r.next(1, 11)).wait();         }          linkedcts.token.throwifcancellationrequested();     } } 

to start code console application main method:

class program {     static void main(string[] args)     {             manager manager = new manager();             manager.start();             //console.readkey();              thread.sleep(5000);             manager.cancel();    } } 

thank help!

the source of problem line:

this.maintoken.register(maincanceled); 

you register callback execute when token cancelled. internally callback delegated parent cancellationtokensource , put in list of callbacks execute when source cancellation requested. in handler do

tokentask.wait(); sourcetask.wait(); 

so callback not completed until related tasks completed. in tasks this

while (!linkedtoken.iscancellationrequested) {     // loop here } 

so tasks not completed until cancellation requested.

now tricky part: when create linked token source

cancellationtokensource.createlinkedtokensource(maintoken) 

it also put callback in list of parent (maintoken) token source. when callback executed - linked token source becomes cancelled too. callback after callback in list.

so deadlocked, because first callback (yours) waits tasks complete, tasks wait linked token iscancellationrequested equals true, , linked token source waits it's own callback complete set flag.

to solve issue, remove callback, or write in way not block waiting related task complete, or change tasks not wait on linked token source iscancellationrequested flag.


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -