This chapter is actually very important, but now I have not encountered in the work, it should be I have not thought of the relationship it ~
ContinueWith is a task based on its own status, deciding what to do next. That is, after the task is run, the XX statement in Task.continuewith (XX) is executed, but whether it is executed, how it is executed, and so on, needs to see the task running.
static int Taskmethod (string name, int seconds)
{
Console.WriteLine ("Task method:task {0} is running on a thread ID {1}. is thread pool thread: {2} ",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread );
Thread.Sleep (timespan.fromseconds (seconds));
return * seconds;
}
var firsttask = new Task<int> (() => Taskmethod ("First task", 3);
Firsttask.continuewith (T => Console.WriteLine ("First task returns the result is {0}.") Thread ID {1}, whether thread pool threads: {2} ",
T.result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
taskcontinuationoptions.onlyonrantocompletion);
Firsttask.start ();
The Order of Start () and ContinueWith () is not related, and continuewith () waits until the Firsttask state reaches IsCompleted, Because of the onlyonrantocompletion in the taskcontinuationoptions.
It is important to note that the parameters in ContinueWith () require a task, that is, Firsttask is passed as a parameter, and ContinueWith () runs in threads in the thread pool.
I think the more important point is that the statements in ContinueWith () as a new block of statements, they are independent of the main thread. In any case, they are judged, if the status is dissatisfied enough, then they do not execute; When multiple states are specified, a reasonable corresponding state is used.
Look at the following code:
Console.WriteLine ("Main thread thread ID {0}, whether thread pool thread: {1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
var firsttask = new Task<int> (() => Taskmethod ("First task", 3);
var secondtask = new Task<int> (() => Taskmethod ("Second task", 2);
Firsttask.continuewith (T => Console.WriteLine ("Follow-up: The return result for the first task is {0}.) Thread ID {1}, whether thread pool threads: {2} ",
T.result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
taskcontinuationoptions.onlyonrantocompletion);
Firsttask.start ();
Secondtask.start ();
Thread.Sleep (Timespan.fromseconds (4)); Give enough time for Firsttask, Secondtask and subsequent operations to complete.
Task continuation = Secondtask.continuewith (T => Console.WriteLine ("Follow-up: The return result for the second task is {0}.) Thread ID {1}, whether thread pool threads: {2} ",
T.result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
taskcontinuationoptions.onlyonrantocompletion | taskcontinuationoptions.executesynchronously);
Here the main thread sleeps for a full 4 seconds, enough to allow Firsttask and Secondtask to run two tasks, and then, since Secondtask's subsequent addition to accepting onlyonrantocompletion, Also accept executesynchronously. Therefore, in the subsequent operation, because the main thread has not finished, so executesynchronously is recognized, so the follow-up is secondtask in the main thread run.
However, if the 4-second sleep annotation is dropped, the Secondtask can only accept onlyonrantocompletion, so it runs in the thread pool because the main thread ends very early.