C# · 12月 20, 2021

C#线程安全使用(一)

关于Task的使用,一直都是半知半解,最近终于有时间详细的看了一遍MSDN,作为备忘录,将心得也记录下来和大家分享。

首先,根据MSDN的描述,Task是FrameWork4引进的新功能,他和ConCurrent命名空间一起被引进,用来替代Thread的使用。

根据我的使用,个人觉得,他确实比Thead的功能要丰富一些。

先一个最简单的例子

<span style=”color: #0000ff;”>namespace<span style=”color: #000000;”> TaskConsole
{
<span style=”color: #0000ff;”>class<span style=”color: #000000;”> Program
{
<span style=”color: #0000ff;”>static <span style=”color: #0000ff;”>void Main(<span style=”color: #0000ff;”>string<span style=”color: #000000;”>[] args)
{
<span style=”color: #008000;”>//<span style=”color: #008000;”>当前线程标识
<span style=”color: #000000;”> Console.WriteLine(Thread.CurrentThread.GetHashCode());

Task task </span>= <span style=”color: #0000ff;”&gt;new</span><span style=”color: #000000;”&gt; Task(run); Console.WriteLine(</span><span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;任务标识:</span><span style=”color: #800000;”&gt;”</span> + task.GetHashCode() + <span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;,状态:</span><span style=”color: #800000;”&gt;”</span> + task.Status);<span style=”color: #008000;”&gt;//</span><span style=”color: #008000;”&gt;状态 </span>

<span style=”color: #000000;”> task.Start();
Console.WriteLine(<span style=”color: #800000;”>”<span style=”color: #800000;”>任务标识:<span style=”color: #800000;”>” + task.GetHashCode() + <span style=”color: #800000;”>”<span style=”color: #800000;”>,状态:<span style=”color: #800000;”>” + task.Status);<span style=”color: #008000;”>//<span style=”color: #008000;”>状态

</span><span style=”color: #008000;”&gt;//</span><span style=”color: #008000;”&gt;任务完成<a href=”https://www.jb51.cc/tag/houzhixing/” target=”_blank” class=”keywords”>后执行</a>新任务</span> Action<Task> ation = <span style=”color: #0000ff;”&gt;new</span> Action<Task><span style=”color: #000000;”&gt;(taskStart); task.ContinueWith(ation); Console.Read(); } </span><span style=”color: #0000ff;”&gt;public</span> <span style=”color: #0000ff;”&gt;static</span> <span style=”color: #0000ff;”&gt;void</span><span style=”color: #000000;”&gt; taskStart(Task task) { task </span>= <span style=”color: #0000ff;”&gt;new</span><span style=”color: #000000;”&gt; Task(run); task.Start(); </span><span style=”color: #008000;”&gt;//</span><span style=”color: #008000;”&gt;如果注释上面两句话,则任务标识为 task.ContinueWith(ation)中task的任务</span> Console.WriteLine(<span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;任务标识:</span><span style=”color: #800000;”&gt;”</span> + task.GetHashCode() + <span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;,状态:</span><span style=”color: #800000;”&gt;”</span> + task.Status + <span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;,当前线程:</span><span style=”color: #800000;”&gt;”</span> + Thread.CurrentThread.GetHashCode());<span style=”color: #008000;”&gt;//</span><span style=”color: #008000;”&gt;状态</span>

<span style=”color: #000000;”>
}

</span><span style=”color: #0000ff;”&gt;public</span> <span style=”color: #0000ff;”&gt;static</span> <span style=”color: #0000ff;”&gt;void</span><span style=”color: #000000;”&gt; run() { Console.WriteLine(</span><span style=”color: #800000;”&gt;”</span><span style=”color: #800000;”&gt;this is run</span><span style=”color: #800000;”&gt;”</span><span style=”color: #000000;”&gt;); }}

}

解释几个方法:

一,task.GetHashCode(),是获取Task实例的唯一标识,每个Task都不一样。但是,经过我的测试发现,Task.GetHashCode()并不等于Thread.CurrentThread.GetHashCode()。

二,task.ContinueWith(),是任务结束后继续执行任务的方法,传一个Action,当任务结束后,触发该Action。

运行结果如下,任务刚new出来的时候,task就又状态了,是Created,一但运行了,状态就是WaitingToRun。

根据MSDN的说明,Task.State是获取TaskState的枚举值,其枚举值代表的意义如下(直接复制了MSDN的解释)

<th class="descriptionColumn">说明</tr></td> dio/dd997396.aspx">任务取消。 </td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr>该任务已完成执行,正在隐式等待附加的子任务完成。</td></tr></td></td></tr></table>