编写代码的过程中经常会遇到需要并行操作的时候,此时就需要使用到多线程操作,.net中提供了多种操作多线程的方法,这里介绍最简单的一种—-通过ThreadPool.QueueUserWorkItem。
首先看实例代码
ThreadPool.QueueUserWorkItem(DoSomeThing);
private void DoSomeThing(object state)
{
for (int i = 0; i < int.MaxValue; i++)
{
for (int j = 0; j < int.MaxValue; j++)
{
if (j == int.MaxValue - 1)
{
i++;
}
}
}
}
其实灰常简单,上面定义了一个测试方法DoSomeThing用于模拟耗时操作,忧郁的表示正常情况应该不会有人会写出这样的方法,当需要异步调用DoSomeThing时,只需要通过调用QueueUserWorkItem 方法,并将DoSomeThing作为回调函数传入,即可异步调用DoSomeThing方法,此时线程池中的某一个线程将会调用DoSomeThing方法。
接着,介绍一下异步操作的取消,即在异步操作的执行过程中,强制停止函数的执行
修改一下上面的DoSomeThing方法如下
private void <span style="font-family: Arial, Helvetica, sans-serif;">DoSomeThing</span>(CancellationToken token, object state)
{
for (int i = 0; i < int.MaxValue; i++)
{
for (int j = 0; j < int.MaxValue; j++)
{
if (token.IsCancellationRequested)
{
break;
}
<pre name="code" class="csharp"><span style="white-space:pre"> </span>if (j == int.MaxValue - 1)
{
i++;
}
} if (token.IsCancellationRequested) { break; } } }
这次的DoSomeThing方法多了一个CancellationToken类型的参数,通过它可以实时探测到方法是否被取消,其使用方法如下:
首先,新建一个CancellationTokenSource对象
CancellationTokenSource cancelSource = new CancellationTokenSource();
之后将CancellationTokenSource对象的token通过回调方法传入
ThreadPool.QueueUserWorkItem((o) => { DoSomeThing(cancelSource.Token, o); });
因为QueueUserWorkItem的回调函数要求只有一个参数,此处使用了lambda构建了一个含有一个参数的匿名函数,并将cancelSource.Token 传入,就这样,我们新建了一个可取消的异步操作。
当我们需要将异步操作中断时,我们只需要调用一下CancellationTokenSource的cancel方法即可,如下:
cancelSource.Cancel();
在这里CancellationTokenSource的作用其实相当于一个全局状态变量,如果仅仅只是为了实现任务的中断,完全可以使用全局变量来取代,我们可以再次改写DoSomeThing函数如下:
int statenum=0;
private void DoSomeThing(object state)
{
for (int i = 0; i < int.MaxValue; i++)
{
for (int j = 0; j < int.MaxValue; j++)
{
if (statenum == 1)
{
break;
}
if (j == int.MaxValue - 1)
{
i++;
}
}
if (statenum == 1)
{
break;
}
}
}
此时,如果在耗时操作执行过程中将statenum变量置成1,也可实现中断的效果,当然,CancellationTokenSource还有其他的功能,这里就不做深入的探讨了,详情可查阅msdn