针对你所提出的问题,我会给出逐步的解释和示例演示,来详细地讲解如何运用C#的取消令牌CancellationTokenSource。
什么是CancellationTokenSource?
CancellationTokenSource是一个用于协作取消多个任务的机制。它提供了一种向多个任务同时发出取消信号的方法。
在使用CancellationTokenSource之前,我们需要创建一个CancellationTokenSource实例。CancellationTokenSource实例包含一个CancellationToken(取消令牌),并与多个任务共享。当我们调用CancellationToken的Cancel方法时,与该CancellationTokenSource相关联的所有任务都会收到取消请求。
创建CancellationTokenSource
我们可以通过CancellationTokenSource的构造函数来创建CancellationTokenSource实例,如下所示:
var cts = new CancellationTokenSource();
取消令牌
当我们调用CancellationTokenSource实例的Cancel方法时,与该CancellationTokenSource相关联的所有任务都会收到取消请求,如下所示:
cts.Cancel();
取消令牌的注册
当我们创建任务时,我们可以将CancellationToken对象传递给任务。然后,任务可以在其长时间运行的操作的适当间隙中检查该令牌,以便在用户请求取消时退出长时间运行的操作。下面是一个示例:
public static void DoSomeWork(CancellationToken ct)
{
// Do some work here.
while (true)
{
// Check if cancellation is requested.
if (ct.IsCancellationRequested)
{
break;
}
// Do some more work here.
}
}
在上面的示例中,我们可以看到,我们使用了ct.IsCancellationRequested参数,来判断当前是否请求取消令牌。
如何运用CancellationTokenSource?
下面我们将给出两个示例,来演示如何运用CancellationTokenSource。
示例一:取消非托管资源的使用
我们假设我们创建了一个用于访问非托管资源的类UnmanagedResourceAccessor。该类的构造函数接受一个CancellationToken参数,以便在取消请求时释放资源。下面是示例代码:
public class UnmanagedResourceAccessor : IDisposable
{
// The unmanaged resource we are accessing.
private IntPtr _resource;
// The token that determines if we are canceled or not.
private CancellationToken _cancellationToken;
// Constructor.
public UnmanagedResourceAccessor(IntPtr resource, CancellationToken cancellationToken)
{
_resource = resource;
_cancellationToken = cancellationToken;
}
// Release the unmanaged resource.
private void ReleaseResource()
{
// Implement release logic here.
}
// Dispose the object.
public void Dispose()
{
ReleaseResource();
}
}
下面是一个使用UnmanagedResourceAccessor类的示例:
public void CancelableOperation()
{
// Create a cancellation token source.
using (var cancellationTokenSource = new CancellationTokenSource())
{
// Create an instance of our unmanaged resource accessor.
var unmanagedResourceAccessor = new UnmanagedResourceAccessor(GetResourceHandle(), cancellationTokenSource.Token);
try
{
// Do some work using the unmanaged resource accessor.
// Possibly long running operation that needs to be cancelable.
}
catch (OperationCanceledException)
{
// The operation was canceled.
// Clean up any resources used.
}
finally
{
// Dispose of the unmanaged resource accessor.
unmanagedResourceAccessor.Dispose();
}
}
}
在上面的示例中,我们使用了using关键字来确保CancellationTokenSource及UnmanagedResourceAccessor类实例的正确释放。如果我们在DoSomeWork方法中检测到了取消请求,那么就可以使用OperationCanceledException来抛出并处理取消操作。
示例二:取消长时间运行的操作
下面是针对长时间运行的操作的示例代码:
public void CancelableLongRunningOperation(CancellationToken ct)
{
var rnd = new Random();
var counter = 0;
while (!ct.IsCancellationRequested && counter < 10)
{
Console.WriteLine($"{counter}. Doing some work...");
// Simulate long running operation.
Thread.Sleep(rnd.Next(500, 2000));
counter++;
}
if (ct.IsCancellationRequested)
{
Console.WriteLine("Canceled!");
}
else
{
Console.WriteLine("Finished!");
}
}
上述示例中模拟了一个长时间运行的操作,并且在运行过程中,检查了取消令牌是否被请求,如果被请求,则退出循环并处理取消请求。
下面是怎么使用CancellationTokenSource及CancelableLongRunningOperation方法的示例代码:
public void RunCancelableLongRunningOperation()
{
// Create a CancellationTokenSource.
var cts = new CancellationTokenSource();
var ct = cts.Token;
// Do some work.
var task = Task.Factory.StartNew(() => CancelableLongRunningOperation(ct), ct);
// Wait for a key press, then cancel the operation.
Console.WriteLine("Press any key to cancel.");
Console.ReadKey();
cts.Cancel();
try
{
// Wait for task to complete or throw an exception.
task.Wait(ct);
}
catch (AggregateException ex)
{
Console.WriteLine(ex.InnerException.Message);
}
}
上面的代码中,我们首先创建了一个CancellationTokenSource实例,然后我们使用Task.Factory.StartNew方法附加了一个长时间运行的任务,然后等待用户按下按键以请求取消令牌。最后,我们用try-catch块来等待任务完成,或者在取消请求时抛出异常。
这就是如何运用CancellationTokenSource的示例攻略。希望我的回答能够对你有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:运用示例简单讲解C#取消令牌CancellationTokenSource - Python技术站