. Net TPL has great flexibility, and you will find that the same operation has many different implementation methods. As the title says, let's take a look at this simple operation: cancel the execution of the task, and then execute the code in the current synchronizationcontext. Of course, all operations must be asynchronous, so you cannot use methods such as task. Wait.
There are three implementation methods I have come up.
The first step is preparation. First, write a method to execute a task that can be canceled. Then the specific implementation code will directly call this method:
// Execute a task that can be canceled
Static task newcancellabletask (cancellationtoken token)
{
Return Task. Run () =>
{
While (true)
{
System. Threading. thread. Sleep (1000 );
Token. throwifcancellationrequested ();
}
});
}
Next, let's look at three specific implementations.
Directory
- Method 1: Use await
- Method 2: Use continuewith and taskschedith
- Method 3: Use the cancellationtoken. Register Method
Returned directory
Method 1: Use await
This must be the first choice. The await of C #5.0 hides many logics in TPL, so that the code that can be executed asynchronously looks similar to synchronous execution. The following code:
VaR CTS = new cancellationtokensource ();
// Cancel the operation
CTS. cancelafter (1000 );
Try
{
Await newcancellabletask (CTS. Token );
}
Catch (operationcanceledexception)
{
// Collect operationcanceledexception
MessageBox. Show ("Operation canceled ");
}
After several seconds, the "Operation canceled" dialog box is displayed.
Returned directory
Method 2: Use continuewith and taskschedith
The second method is to use task. continuewith and use:
Taskcontinuationoptions. onlyoncanceled
To ensure that subsequent operations are performed only after the task is canceled.
Because await is not used, we need to execute synchronizationcontext by ourselves. The method is to use taskscheduler. fromcurrentsynchronizationcontext to return a taskscheduler created from the current synchronizationcontext.
Task. continuewith has many reloads. We use this one:
Task <tresult> continuewith <tresult> (func <task, tresult> continuationfunction, cancellationtoken, taskcontinuationoptions continuationoptions, taskscheduler Scheduler );
Final code:
VaR CTS = new cancellationtokensource ();
// Cancel the operation
CTS. cancelafter (1000 );
// Continuewith
Newcancellabletask (CTS. Token). continuewith (
T => MessageBox. Show ("Operation canceled "),
Cancellationtoken. None,
Taskcontinuationoptions. onlyoncanceled,
Taskschedation. fromcurrentsynchronizationcontext ());
(The continuewith task actually returns a task <messageboxresult>)
Similarly, the operation is successful.
Returned directory
Method 3: Use the cancellationtoken. Register Method
The cancellationtoken type has a register method that can pass in a delegate. When the cancellationtoken is canceled, the Delegate will be called. What's more, it also has a usesynchronizationcontext parameter to specify whether the callback method is executed on the current synchronizationcontext. Of course, the register method can also pass an additional parameter, which is not required in this example.
: Cancellationtoken. Register Method parameters:
The implementation code using this method is as follows:
VaR CTS = new cancellationtokensource ();
// Registration operation
CTS. Token. Register () => MessageBox. Show ("Operation canceled"), true );
// Cancel the operation
CTS. cancelafter (1000 );
// Execute the task directly without any other operations.
Newcancellabletask (CTS. Token );
This method is rare, but it looks good.