Threading of the CLR via C #-collaborative cancellation and timeouts
Threading of the CLR via C #-collaborative cancellation and timeouts
Collaborative cancellation and timeouts
Collaborative cancellation and timeouts
To create a collaborative cancellation step:
- First, create a System.Threading.CancellationTokenSource object.
public sealed class CancellationTokenSource : IDisposable
{
// 一个引用类型
public void Dispose(); // 释放资源(比如WaitHandle)
public Boolean IsCancellationRequested { get; }
public CancellationToken Token { get; }//通过这个属性获得Token并传递给操作。
public void Cancel(); // 内部调用Cancel并传递false
public void Cancel(Boolean throwOnFirstException);
...
}
- One or more cancellationtoken are obtained through the Cancellationtokensource.token property and passed to the operation.
public struct CancellationToken
{
// 一个值类型
public static CancellationToken None { get; }
public Boolean IsCancellationRequested{ get; } // 由非通过Task调用的操作调用
public void ThrowIfCancellationRequested(); // 由通过Task调用的操作调用
//CancellationTokenSource 取消时,WaitHandle 会收到信号
public WaitHandle WaitHandle { get; }
public Boolean CanBeCanceled { get; } // 很少使用
public CancellationTokenRegistration Register(Action<Object> callback, Object state,
Boolean useSynchronizationContex); // 未列出更简单的重载版本
}
- The Iscancellationrequest property is queried periodically in the method that needs to be canceled.
internal static class CancellationDemo
{
public static void Go()
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.Token.Register(() => Console.WriteLine("cancel callbace!!!"));
var restration = cts.Token.Register(o => Console.WriteLine("Cancel callback{0}!!!", o), 5, true);
restration.Dispose();
ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));
Console.WriteLine("Press Enter to cancel");
Console.ReadLine();
cts.Cancel();
Console.ReadLine();
}
private static void Count(CancellationToken token, Int32 countTo)
{
for (int count = 0; count < countTo; count++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Count is cancelled");
break;
}
Console.WriteLine(count);
Thread.Sleep(200);
}
Console.WriteLine("Count is done");
}
}
PS: If you want to perform an operation that is not allowed to be canceled, you can pass the Cancellationtokensource.none property to the operation.
- If required, you can call CancellationToken's Register method to register the callback at the time of cancellation. You can remove the registered callback function by calling its Dispose method by callcellationtakenregistration the method's return value.
- You can also link another set of CancellationTokenSource to create a new CancellationTokenSource object.
var cts1 = new CancellationTokenSource();
cts1.Token.Register(() => Console.WriteLine("cts1 cancelled"));
var cts2 = new CancellationTokenSource();
cts2.Token.Register(() => Console.WriteLine("cts2 canceled"));
//创建一个新的,它在cts1或cts2取消时取消
-
var linkedcts Span class= "pun" >= cancellationtokensource createlinkedtokensource ( cts1 token cts2 token
linkedCts.Token.Register(() => Console.WriteLine("linkedCts canceled"));
- You can also specify the delay time by CancellationTokenSource the constructor or by calling Cancelafter to cancel automatically.
public sealed class CancellationTokenSource : IDisposable
{
public CancellationTokenSource(Int32 millisecondsDelay);
public CancellationTokenSource(TimeSpan delay);
public void CancelAfter(Int32 millisecondsDelay);
public void CancelAfter(TimeSpan delay);
...
}
From for notes (Wiz)
Threading of the CLR via C #-collaborative cancellation and timeouts