前言:因为Task是.NET 4并行编程最为核心的一个类,也我们在是在并行编程常常打交道的类,所以,对Task对全面的了解很有必要。
while (true)
{
if (token.IsCancellationRequested)
{
// tidy up and release resources
throw new OperationCanceledException(token);
}
else
{
// do a unit of work
}
}
while (true)
{
token.ThrowIfCancellationRequested();
// do a unit of work
}
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete.Press enter to finish."); Console.ReadLine(); } |
static void Main(string[] args)
{
// create the cancellation token source
CancellationTokenSource tokenSource = new CancellationTokenSource();
// create the cancellation token
CancellationToken token = tokenSource.Token;
// create the task
Task task = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task cancel detected");
throw new OperationCanceledException(token);
}
else
{
Console.WriteLine("Int value {0}", i);
}
}
}, token);
// register a cancellation delegate
token.Register(() =>
{
Console.WriteLine(">>>>>> Delegate Invoked\n");
});
// wait for input before we start the task
Console.WriteLine("Press enter to start task");
Console.WriteLine("Press enter again to cancel task");
Console.ReadLine();
// start the task
task.Start();
// read a line from the console.
Console.ReadLine();
// cancel the task
Console.WriteLine("Cancelling task");
tokenSource.Cancel();
// wait for input before exiting
Console.WriteLine("Main method complete.Press enter to finish.");
Console.ReadLine();
}
3.用Wait Handle还检测Task是否被取消
第三种方法检测task是否被cancel就是调用CancellationToken.WaitHandle属性。对于这个属性的详细使用,在后续的文章中会深入的讲述,在这里主要知道一点就行了:CancellationToken的WaitOne()方法会阻止task的运行,只有CancellationToken的cancel()方法被调用后,这种阻止才会释放。
在下面的例子中,创建了两个task,其中task2调用了WaitOne()方法,所以task2一直不会运行,除非调用了CancellationToken的Cancel()方法,所以WaitOne()方法也算是检测task是否被cancel的一种方法了。
代码
static void Main(string[] args)
{
// create the cancellation token source
CancellationTokenSource tokenSource = new CancellationTokenSource();
// create the cancellation token
CancellationToken token = tokenSource.Token;
// create the task
Task task1 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task cancel detected");
throw new OperationCanceledException(token);
}
else
{
Console.WriteLine("Int value {0}", i);
}
}
}, token);
// create a second task that will use the wait handle
Task task2 = new Task(() =>
{
// wait on the handle
token.WaitHandle.WaitOne();
// write out a message
Console.WriteLine(">>>>> Wait handle released");
});
// wait for input before we start the task
Console.WriteLine("Press enter to start task");
Console.WriteLine("Press enter again to cancel task");
Console.ReadLine();
// start the tasks
task1.Start();
task2.Start();
// read a line from the console.
Console.ReadLine();
// cancel the task
Console.WriteLine("Cancelling task");
tokenSource.Cancel();
// wait for input before exiting
Console.WriteLine("Main method complete.Press enter to finish.");
Console.ReadLine();
}
4.取消多个Task
我们可以使用一个CancellationToken来创建多个不同的Tasks,当这个CancellationToken的Cancel()方法调用的时候,使用了这个token的多个task都会被取消。
代码
static void Main(string[] args)
{
// create the cancellation token source
CancellationTokenSource tokenSource = new CancellationTokenSource();
// create the cancellation token
CancellationToken token = tokenSource.Token;
// create the tasks
Task task1 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Task 1 - Int value {0}", i);
}
}, token);
Task task2 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, token);
// wait for input before we start the tasks
Console.WriteLine("Press enter to start tasks");
Console.WriteLine("Press enter again to cancel tasks");
Console.ReadLine();
// start the tasks
task1.Start();
task2.Start();
// read a line from the console.
Console.ReadLine();
// cancel the task
Console.WriteLine("Cancelling tasks");
tokenSource.Cancel();
// wait for input before exiting
Console.WriteLine("Main method complete.Press enter to finish.");
Console.ReadLine();
}
5.创建组合的取消Task的Token
我们可以用CancellationTokenSource.CreateLinkedTokenSource()方法来创建一个组合的token,这个组合的token有很多的CancellationToken组成。主要组合token中的任意一个token调用了Cancel()方法,那么使用这个组合token的所有task就会被取消。代码如下:
代码
static void Main(string[] args)
{
// create the cancellation token sources
CancellationTokenSource tokenSource1 = new CancellationTokenSource();
CancellationTokenSource tokenSource2 = new CancellationTokenSource();
CancellationTokenSource tokenSource3 = new CancellationTokenSource();
// create a composite token source using multiple tokens
CancellationTokenSource compositeSource =
CancellationTokenSource.CreateLinkedTokenSource(
tokenSource1.Token, tokenSource2.Token, tokenSource3.Token);
// create a cancellable task using the composite token
Task task = new Task(() =>
{
// wait until the token has been cancelled
compositeSource.Token.WaitHandle.WaitOne();
// throw a cancellation exception
throw new OperationCanceledException(compositeSource.Token);
}, compositeSource.Token);
// start the task
task.Start();
// cancel one of the original tokens
tokenSource2.Cancel();
// wait for input before exiting
Console.WriteLine("Main method complete.Press enter to finish.");
Console.ReadLine();
}
6.判断一个Task是否已经被取消了
可以使用Task的IsCancelled属性来判断task是否被取消了。代码如下:
代码
static void Main(string[] args)
{
// create the cancellation token source
CancellationTokenSource tokenSource1 = new CancellationTokenSource();
// create the cancellation token
CancellationToken token1 = tokenSource1.Token;
// create the first task, which we will let run fully
Task task1 = new Task(() =>
{
for (int i = 0; i < 10; i++)
{
token1.ThrowIfCancellationRequested();
Console.WriteLine("Task 1 - Int value {0}", i);
}
}, token1);
// create the second cancellation token source
CancellationTokenSource tokenSource2 = new CancellationTokenSource();
// create the cancellation token
CancellationToken token2 = tokenSource2.Token;
// create the second task, which we will cancel
Task task2 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
token2.ThrowIfCancellationRequested();
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, token2);
// start all of the tasks
task1.Start();
task2.Start();
// cancel the second token source
tokenSource2.Cancel();
// write out the cancellation detail of each task
Console.WriteLine("Task 1 cancelled? {0}", task1.IsCanceled);
Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);
// wait for input before exiting
Console.WriteLine("Main method complete.Press enter to finish.");
Console.ReadLine();
}
今天就写到这里,比较的简单,都是一些很基础的东西,只有这样,后面深入讲解的时候才更加的顺利。