Task. Run and Task. Factory. StartNew, taskfactory. startnew

Source: Internet
Author: User

Task. Run and Task. Factory. StartNew, taskfactory. startnew

In. Net 4Medium,Task.Factory.StartNewIs to start a newTask. It has many overload methods, so that it can be very flexible in use. By setting optional parameters, you can pass in any State, cancel the task to continue execution, or even control the scheduling behavior of the task. All these capabilities also increase complexity. You must know when to use the overload method and what scheduling method to provide. AndTask.Factory.StartNewThis method is not concise and clear. At least it is not fast enough to use the main scenario. Generally, the main scenario is to throw a job to a background thread for execution.

Therefore. NET Framework 4.5 Developer Preview, Microsoft introduced a newTask.RunMethod. The new method is not used to replace the old one.Task.Factory.StartNewMethod, but provides a way to useTask.Factory.StartNewMethod, rather than specifying the series of parameters. This is a shortcut. In fact,Task.RunInternal implementation logic andTask.Factory.StartNewSimilarly, some default parameters are passed. For example, when you useTask.Run:

Task.Run(someAction);

In fact, it is equivalent:

Task.Factory.StartNew(someAction, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Use these default parameters,Task.RunIt can be used in most cases-simply hand the task to the background thread pool for execution (this is also used)TaskScheduler.DefaultParameter ). This does not meanTask.Factory.StartNewThe method does not need to be used any more. It still has many important functions. You can controlTaskCreationOptionsParameters to control the actions of a task, you can also controlTaskSchedulerTo control how tasks should be queued and run, you can also use the parameter that accepts the object status in the overload method. For some performance-sensitive code, it can be used to avoid closures and corresponding resource allocation. However, for the simple example above,Task.RunIs the most friendly.

Task.RunEight overload methods are provided to provide the following combinations:

The first two are obvious.TaskIf the overload method of the returned value is used, the task does not return the value.Task<TResult>If you do the return value overload method, the task has a typeTResult. The second point is also accepted.CancellationTokenYou can run the cancel operation before the Task starts, and then the Parallel Task (Task Parallel Library -- TPL) can naturally overload to the canceled state.
The third point is more interesting. It is directly related to the asynchronous language support of C # and Visual Basic in Visual studio 11. UseTask.Factory.StartNewTo show this problem, if you have the following code:

var t = Task.Factory.StartNew(() => {     Task inner = Task.Factory.StartNew(() => {});     return inner; });

HeretIs inferredTask<Task>Because the task delegate type isFunc<TResult>So hereTResultIsTask, SoStartNewMethod returnsTask<Task>, Similarly, I can change it to the following method:

var t = Task.Factory.StartNew(() => {     Task<int> inner = Task.Factory.StartNew(() => 42));     return inner; });

HeretThe type isTask<Task<int>>, Whether the task delegate type isFunc<TResult>,TResultIsTask<int>,StartNewMethod returnsTask<Task<int>>. What is the relationship between them? Consider the following method if we use it:

var t = Task.Factory.StartNew(async delegate {     await Task.Delay(1000);     return 42; });

Used hereasyncKeyword, the compiler maps this delegateFunc<Task<int>>, Calling this delegate will eventually returnTask<int>. Because this delegate isFunc<Task<int>>,TResultIsTask<int>, So the lasttThe typeTask<Task<int>>InsteadTask<int>.

To cope with these situations. Net 4Introduced inUnwrapMethod.UnwrapThere are two methods for overloading, both of which are extension methods andTask<Task>, The other is<Task<TResult>>. Microsoft only needs to name this method Unwrap because it can return the actual results of the task. PairTask<Task>CallUnwrapMethod returns a newTask(Like a proxy for an internal task) represents its internal task. SimilarTask<Task<TResult>>CallUnwrapReturns a newTask<TResult>It represents its internal tasks. However, if an external task fails or is canceled, there will be no internal task. Because no task is completed, the proxy task becomes the status of the external task. Return to the previous example.tIt indicates the return value of an internal task (in this example, the value is 42), so it should be written as follows:

var t = Task.Factory.StartNew(async delegate {     await Task.Delay(1000);     return 42; }).Unwrap();

Now, the variabletIsTask<int>Indicates the result of an asynchronous call.

Now returnTask.RunBecause Microsoft wants developers to use this method to enable background tasks as much as possible, and can workasync/awaitSo Microsoft decidedTask.RunBuilt-in Methodsunwrapping. This is also the content mentioned in the third point above,Task.RunIs acceptable in the overload methodAction(Tasks with no returned values), acceptedFunc<TResult>(ReturnTResultYes.Func<Task>(Return the task of an asynchronous task), and acceptFunc<Task<TResult>>(ReturnsTResultType returned value of the asynchronous task. In general,Task.RunThe method provides the aboveTask.Factory.StartNewSame MethodunwrappingOperation. Therefore, we can write as follows:

var t = Task.Run(async delegate {     await Task.Delay(1000);     return 42; });

tIsTask<int>, HereTask.RunThe reload method is equivalent:

var t = Task.Factory.StartNew(async delegate {     await Task.Delay(1000);      return 42; }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap();

As mentioned above, this is a shortcut.

All the class content mentioned above means that you can useTask.RunCall Standardlambdas/anonymousMethod or asynchronouslambdas/anonymousMethod, always run according to your expected behavior. If you want the task to run in the background and wait for its results, you can write it as follows:

int result = await Task.Run(async () => {     await Task.Delay(1000);     return 42; });

VariableresultIs exactly what you expectedintAnd after the task is called for about one second, the variableresultIs set to 42.

Interestingly, the newawaitKeyword is considered to be equivalentUnwrapA new syntax form of the method. So, if we go back toTask.Factory.StartNewFor example, we can useUnwrapRewrite the code snippet above:

int result = await Task.Factory.StartNew(async delegate {     await Task.Delay(1000);     return 42; }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap();

Alternatively, you can use the secondawaitReplaceUnwrap:

int result = await await Task.Factory.StartNew(async delegate {     await Task.Delay(1000);     return 42; }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Hereawait awaitAlthough it looks awkward, there is no problem.Task.Factory.StartNewMethod returnsTask<Task<int>>Task<Task<int>>UseawaitActually returnTask<int>And thenTask<int>UseawaitLast returnintIsn't that true?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.