. Net4.0 task (task)

Source: Internet
Author: User

A task is a lightweight object for managing parallel work units. It avoids starting special threads by using the CLR thread pool, and can more efficiently use the thread pool. List of task-related classes in the system. Threading. Tasks namespace:

Class Function
Task Manage Work Units
Task <tresult> Manage work units with return values
Taskfactory Create a task
Taskfactory <tresult> Create a task or a continuation task with the same return value
Taskscheduler Manage Task Scheduling
Taskcompletionsource Manual control of task Workflow

Tasks are used to execute tasks in parallel and make full use of multiple cores: in fact, parallel and Plinq are built on the parallel structure of tasks.

Tasks provide a series of powerful features to manage work units, including:

  • Coordinate Task Scheduling
  • Create a parent-child relationship for a task to start from another task
  • Cooperative cancellation Mode
  • No-signal task waiting
  • Attach a continuation task (continuation)
  • Schedules a continuation Task Based on Multiple ancestor tasks
  • Passing an exception to the parent task, continuation task, or task consumer

At the same time, a task implements a local work queue, which allows you to efficiently create fast-executed sub-tasks without the cost of competing in a single work queue. The task parallel library allows you to create hundreds of tasks at minimal cost. However, if you want to create millions of tasks, you must split these tasks into larger units to maintain efficiency.

Create and start a task

You can create a task by using the startnew () method of taskfactory. You can also call the task constructor to create a task and start the task manually. Note that the task is not executed immediately after it is started. It is managed by the taskscheduler.

  • Example of creating a task using the startnew () method of taskfactory:

    // No Return Value
    Task. Factory. startnew () => console. writeline ("task created! "));
    // Return Value
    VaR task = task. Factory. startnew <string> () => "task created! ");
    Console. writeline (task. Result );
  • An example of manually starting a start method is as follows:
    VaR task = new task <string> () => "task created! ");
    Task. Start (); // asynchronous execution
    Console. writeline (task. Result );
  • An example of manually starting a runsynchronously call is as follows:
    VaR task = new task <string> () => "task created! ");
    Task. runsynchronously (); // synchronous execution
    Console. writeline (task. Result );

You can also specify a task status parameter when creating a task. You can access this parameter through the asyncstate attribute of the task. Example:

var task = Task.Factory.StartNew(state => "hello " + state, "Mike");
Console.WriteLine(task.AsyncState);
Console.WriteLine(task.Result);

You can also specify taskcreationoptions, which has the following enumerated values: None, longrunning, preferfairness, and attachedtoparent. The following describes the functions of enumeration values.

  • Longrunning: as its name implies, it is a long-running task. It is recommended that the Task Scheduler allocate a dedicated thread to the task. The reason for this is that long running tasks may block the task queue, resulting in short tasks not being executed. Longrunning is also suitable for blocking tasks.
  • Preferfairness: Fair first, this option suggests that the task scheduler schedule tasks based on the task start time as much as possible. However, it may not do this because it uses local work to steal queues (local work-stealing queues) to optimize task scheduling. This optimization is useful for very small tasks.
  • Attachtoparent: attach to parent task. This option is used to create a subtask. Example of creating a subtask:
    Method 1:
    VaR parent = task. Factory. startnew () =>
    {
    VaR nonchildtask = task. Factory. startnew (
    () => Console. writeline ("I'm not a child task .")
    );
    VaR childtask = task. Factory. startnew (
    () => Console. writeline ("I'm a child task ."),
    Taskcreationoptions. attachedtoparent );
    });
    Method 2:
    Task parent = new task () =>
    {
    Dostep1 ();
    });
    Task task2 = parent. continuewith (prevtask) =>
    {
    Dostep2 ();
    });
    Parent. Start ();
Task waiting

You can use the wait () member method or the result attribute to wait for the task to complete.

When the result attribute is called, the following operations are performed:

  1. If the task has ended, return the task result
  2. If the task has started, wait until the task ends
  3. If the task has not started execution, the task will be executed in the current thread

The task. waitany () Static Method waits for any task to complete. Example:

VaR tasks = new task [3];
For (INT I = 0; I <tasks. length; I ++)
{
Int taskindex = I;
Tasks [I] = task. Factory. startnew () =>
{
Int seed = guid. newguid (). gethashcode ();
Int waittime = new random (SEED). Next (10,100 );
Thread. Sleep (waittime );
Console. writeline ("task {0} finished", taskindex );
});
}
Task. waitany (tasks );
Console. writeline ("completed tasks ");

The task. waitall () Static Method waits for all tasks to be completed. Even if a task throws an exception, it does not terminate the wait. After all tasks are completed, it throws an aggresponexception. This exception aggregates the exceptions thrown by all tasks. Example:

VaR tasks = new task [3];
For (INT I = 0; I <tasks. length; I ++)
{
Int taskindex = I;
Tasks [I] = task. Factory. startnew () =>
{
Int waittime = new random (guid. newguid (). gethashcode (). Next (10,100 );
Thread. Sleep (waittime );
Console. writeline ("task {0} finished", taskindex );
});
}
Task. waitall (tasks );
Console. writeline ("all tasks completed ");
Exception Handling

By default, applications are terminated if the task is not handled. It should be noted that unhandled exceptions in the task will not immediately lead to application termination. The exception will be terminated only when the Garbage Collector recycles the task and calls the Finalize method. If the exception attribute of the task is read, this operation will prevent subsequent application termination.
When the task is completed, all unhandled exceptions are passed to the caller.
An exception that occurs when the wait () method times out must also be handled; otherwise, the application is terminated.
Unhandled exceptions in the subtask are passed to the parent task by bubbling; exceptions in non-subtasks in the nested task are not passed to the previous Task of the subtask, which must be handled independently, otherwise, the application will be terminated.

var task = Task.Factory.StartNew(() =>
{
Task.Factory.StartNew(() => { throw null; }, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(() => { throw null; }, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(() => { throw null; }, TaskCreationOptions.AttachedToParent);
});
task.Wait();

Taskschedexception. unobservedtaskexception static events provide the last method to handle all unprocessed exceptions. By handling this event, you do not need to terminate the application, but replace it with your own exception handling logic.

Cancel task

When creating a task, you can pass in a cancelationtoken parameter to cancel the task safely. Example:

var source = new CancellationTokenSource();
var token = source.Token;
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task starting...");
while (true)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("I'm alive. {0}",DateTime.Now);
Thread.Sleep(1000);
}
},token);

Task.Factory.StartNew(() =>
{
Thread.Sleep(4500);
source.Cancel();
});

try
{
task.Wait();
Console.WriteLine("Task stopped.");
}
catch (AggregateException e)
{
if (e.InnerException is OperationCanceledException)
{
Console.WriteLine("Task canceled.");
}
else
{
Console.WriteLine("errors.");
}
}

If you cancel a task by calling the cancellationtokensource cancel () method, the task will not be terminated immediately until the next time the task is detected to be canceled, operationcanceledexception will be thrown to terminate the task.

If you want to cancel a task by directly throwing an operationcanceledexception exception, you must input the cancelationtoken parameter in the task. Otherwise, the task cannot be in the taskstatus. Canceled state and the onlyoncanceled continuation task is triggered.

In addition, the cancel token can also be passed to the wait and cancelandwait methods to cancel the wait.

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.