C#线程安全使用(四)
这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来。 这里主要讲解下CancellationTokenSource,CancellationTokenSource是用于取消线程,具体使用起来有点另类:首先定义实体,然后将其下的属性ToKen传递给线程,当需要取消线程时,调用下Cancel()方法。例子我依然采用了MSDN的例子,但我做了一些修改,这个例子虽然看起来挺复杂,但还是记录了许多内容。 由于不好理解,我就粗略讲解下: Task ?再介绍下factory.ContinueWhenAll,他包含两个参数Task[] tasks,Action ?方法执行?
英文解释:
CancellationTokenSource source = == =
values[ctr </span>- <span style="color: #800080;">1</span>] =<span style="color: #000000;"> value;
}
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">NO Cancel at task {0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,iteration);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> values;
},token));
}
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">
{
Task</span><<span style="color: #0000ff;">double</span>> fTask =<span style="color: #000000;"> factory.ContinueWhenAll(tasks.ToArray(),(results) </span>=><span style="color: #000000;">
{
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">Calculating overall mean...</span><span style="color: #800000;">"</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">long</span> sum = <span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #0000ff;">int</span> n = <span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #0000ff;">foreach</span> (<span style="color: #0000ff;">var</span> t <span style="color: #0000ff;">in</span><span style="color: #000000;"> results)
{
</span><span style="color: #0000ff;">foreach</span> (<span style="color: #0000ff;">var</span> r <span style="color: #0000ff;">in</span><span style="color: #000000;"> t.Result)
{
sum </span>+=<span style="color: #000000;"> r;
n</span>++<span style="color: #000000;">;
}
}
</span><span style="color: #0000ff;">return</span> sum / (<span style="color: #0000ff;">double</span><span style="color: #000000;">)n;
},token);
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">The mean is {0}.</span><span style="color: #800000;">"</span><span style="color: #000000;">,fTask.Result);
}
</span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (AggregateException ae)
{
</span><span style="color: #0000ff;">foreach</span> (Exception e <span style="color: #0000ff;">in</span><span style="color: #000000;"> ae.InnerExceptions)
{
</span><span style="color: #0000ff;">if</span> (e <span style="color: #0000ff;">is</span><span style="color: #000000;"> TaskCanceledException)
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">Unable to compute mean: {0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,((TaskCanceledException)e).Message);
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">Exception: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> e.GetType().Name);
}
}
Console.ReadLine();
}
} 显示结果图片,每次的结果都不一样的,所以我也是运行了好几次,看这个结果会发现一件事,线程只执行了两个,即当线程2中调用Cancel后,其他线程也被取消了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |