Task.continuewith
The goods, like await, have a "trap". ^^, because writing continuewith is not intuitive as a human "process" thinking, the part written in continuewith brackets is not necessarily only completed after the task of initiating continuewith, such as:
1 namespaceTaskconsole2 {3 class Program4 {5 Static voidMain (string[] args)6 {7 while(true)8 {9 varEnter =console.readline ();Ten One if(enter.) ToLower () = ="Continue") {Entry ();} A Else{ Break; } - } - } the - - Async Static voidDoWork (stringworkername) - { + awaitTask.delay ( +); -Console.WriteLine ("{0} is working @ Thread Id {1}", Workername, System.Threading.Thread.CurrentThread.ManagedThreadId); + } A at Async Static voidDoclean (stringcleaner) - { - awaitTask.delay ( +); -Console.WriteLine ("{0} is cleaning @ Task Id {1}", cleaner, Task.currentid); - } - in Async StaticTask Entry () - { to varTask = Task.Factory.StartNew (() = DoWork ("worker 1")). +ContinueWith (backer = Doclean ("Cleaner 1")). -ContinueWith (backer = Doclean ("Cleaner 2")). theContinueWith (backer = Doclean ("Cleaner 3")); * } $ }Panax Notoginseng}
Run for a try? If there is no await task.delay participation in the process, it looks basically in order, but this one adds immediately to the trap, see
So how do we get continuewith to follow our heart? Yes, there are other parameters to use, let's try it.
1 varTask = Task.Factory.StartNew (() = DoWork ("worker 1")).2ContinueWith (backer = Doclean ("Cleaner 1"), taskcontinuationoptions.notonrantocompletion).3ContinueWith (backer = Doclean ("Cleaner 2"), taskcontinuationoptions.onlyonrantocompletion).4ContinueWith (backer = Doclean ("Cleaner 3"), taskcontinuationoptions.onlyonrantocompletion);
Run, eh, what happened?
Why aren't the cleanup people working? The problem is the parameter "Taskcontinuationoptions.notonrantocompletion", which plays a role, it tells the first cleaner "you can start when the worker task is not done properly", so the Cleaner 1 has no chance to start, it doesn't have a chance to start , after the cleanup 2, Cleanup 3 naturally have no way to start. To here only know ContinueWith and parameters can be used, but did not achieve our goal, continue! Let's change the two void method.
1 Async StaticTask DoWork (stringworkername)2 {3 awaitTask.delay ( +);4Console.WriteLine ("{0} is working @ Thread Id {1}", Workername, System.Threading.Thread.CurrentThread.ManagedThreadId);5 }6 7 Async StaticTask Doclean (stringcleaner)8 {9 awaitTask.delay ( +);TenConsole.WriteLine ("{0} is cleaning @ Task Id {1}", cleaner, Task.currentid); One}
Becomes the method of Task, there is the precondition of control, then change the process of ContinueWith
1 {2 varTaskworker = Task.Factory.StartNew (() = DoWork ("worker 1"));3 awaitTaskworker.result;4 varC1 =awaitTaskworker.continuewith (backer = Doclean ("Cleaner 1"), taskcontinuationoptions.onlyonrantocompletion);5 varC2 =awaitC1. ContinueWith (backer = Doclean ("Cleaner 2"), taskcontinuationoptions.onlyonrantocompletion);6 varC3 =awaitC2. ContinueWith (backer = Doclean ("Cleaner 3"), taskcontinuationoptions.onlyonrantocompletion);7}
Separate the piles of ContinueWith that were originally written together, let them each "own identity", and sequentially inherit the last task, which is enabled only if the specified task execution completes to the Rantocompletion state, and the use of await guarantees Taskworker Run completed C1 will not execute, C1 run out of C2 will execute, C2 run after C3 will be executed. To this, it seems to have fulfilled our request.
. Net asynchronous Handy Note (ii)