这篇文章介绍了C#多线程之取消架构,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
.NET 4.5 中包含取消架构,允许以标准方式取消长时间运行的任务。每个阻塞调用都应支持这种机制。但目前,并不是所有阻塞调用都实现了这个新技术。已经实现了这种机制的技术有任务(),并发集合类(),并行LINQ()和几种同步机制。
取消架构基于协作行为,它不是强制的。长时间运行的任务会检查它是否被取消,并返回控制权。
支持取消的方法接受一个CancellationToken参数。这个类定义了IsCancellationRequested属性,其中长时间运行的操作可以检查它是否应终止。使用Register()方法注册一个将在取消此 System.Threading.CancellationToken 时调用的委托。它在调用Cancel()方法取消操作时调用。
1.Parallel.For()方法的取消
Parallel类提供了For()方法的重载版本,在重载版本中,可以传递ParallelOptions类型的参数。使用ParallelOptions类型,可以传递一个CancellationToken参数。CancellationToken参数通过创建CancellationTokenSource来生成。由于CancellationTokenSource实现了ICancelableOperation接口,因此可以用CancellationToken注册,并允许使用Cancle(),CancleAfter()等方法取消操作。
示例:
static void CancelParallelFor()
{
var cts = new CancellationTokenSource();
cts.Token.Register( ()=> Console.WriteLine("token canceled!"));
cts.CancelAfter(1000);
try
{
ParallelLoopResult plr =
Parallel.For(0, 100, new ParallelOptions { CancellationToken = cts.Token },
x => {
Console.WriteLine("loop {0} started", x);
Thread.Sleep(1000);
Console.WriteLine("loop {0} fininshed!", x);
});
}
catch (OperationCanceledException ex)
{
Console.WriteLine(ex.Message);
}
}
输出:
在For循环的实现代码中,Parallel类验证CancellationToken的结果,并取消操作。一旦取消操作,For()方法就抛出一个OperationCanceledException类型的异常。
由输出可看出,当取消操作时,已启动的操作允许完成,因为取消操作总是以协作方式进行,以避免在取消迭代操作的中间泄露资源。
2.任务的取消
任务的取消类似Parallel.For()方法的取消。首先,创建一个CancellationTokenSource。如果只需要一个取消标记,可以访问Task.Factory.CancellationToken,以使用默认的取消标记。任务通过TaskFactory对象接受取消标记。在构造函数中,把取消标记赋予TaskFactory。这个取消标记又任务用于检查CancellationToken的IsCancellationRequested属性,以确定是否请求了取消。
示例:
static void CancelTask()
{
var cts = new CancellationTokenSource();
cts.Token.Register(() => Console.WriteLine("task cancelled!"));
cts.CancelAfter(2000);
try
{
Task t = Task.Run(() =>
{
CancellationToken token = cts.Token;
Console.WriteLine("task stared!");
for (int i = 0; i < 20; i++)
{
Thread.Sleep(500);
if (cts.IsCancellationRequested)
{
Console.WriteLine("cancelled!");
token.ThrowIfCancellationRequested();//抛出异常
break;
}
Console.WriteLine("in loop!");
}
}, cts.Token);
t.Wait();
}
catch (AggregateException ex)
{
Console.WriteLine("exception:{0},{1}",ex.GetType().Name,ex.Message);
foreach (var innerEx in ex.InnerExceptions)
{
Console.WriteLine("exception:{0},{1}", ex.InnerException.GetType().Name, ex.InnerException.Message);
}
}
}
输出:
到此这篇关于C#多线程之取消架构的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持得得之家。
本文标题为:C#多线程之取消架构介绍


基础教程推荐
- Unity 如何获取鼠标停留位置下的物体 2023-04-10
- C#中的Linq to JSON操作详解 2023-06-08
- 实例详解C#实现http不同方法的请求 2022-12-26
- C#中 Json 序列化去掉null值的方法 2022-11-18
- C# 解析XML和反序列化的示例 2023-04-14
- C#调用摄像头实现拍照功能的示例代码 2023-03-09
- Unity shader实现高斯模糊效果 2023-01-16
- C#通过标签软件Bartender的ZPL命令打印条码 2023-05-16
- c# – USING块在网站与Windows窗体中的行为不同 2023-09-20
- C#获取指定目录下某种格式文件集并备份到指定文件夹 2023-05-30