Created
November 18, 2019 12:01
-
-
Save cilliemalan/77cb177d9045244bfb9a939f8b96e9df to your computer and use it in GitHub Desktop.
An awaiter for CancellationToken
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Runtime.CompilerServices; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace Core | |
{ | |
public static class AsyncExtensions | |
{ | |
/// <summary> | |
/// Allows a cancellation token to be awaited. | |
/// </summary> | |
[EditorBrowsable(EditorBrowsableState.Never)] | |
public static CancellationTokenAwaiter GetAwaiter(this CancellationToken ct) | |
{ | |
// return our special awaiter | |
return new CancellationTokenAwaiter | |
{ | |
CancellationToken = ct | |
}; | |
} | |
/// <summary> | |
/// The awaiter for cancellation tokens. | |
/// </summary> | |
[EditorBrowsable(EditorBrowsableState.Never)] | |
public struct CancellationTokenAwaiter : INotifyCompletion, ICriticalNotifyCompletion | |
{ | |
public CancellationTokenAwaiter(CancellationToken cancellationToken) | |
{ | |
CancellationToken = cancellationToken; | |
} | |
internal CancellationToken CancellationToken; | |
public object GetResult() | |
{ | |
// this is called by compiler generated methods when the | |
// task has completed. Instead of returning a result, we | |
// just throw an exception. | |
if (IsCompleted) throw new OperationCanceledException(); | |
else throw new InvalidOperationException("The cancellation token has not yet been cancelled."); | |
} | |
// called by compiler generated/.net internals to check | |
// if the task has completed. | |
public bool IsCompleted => CancellationToken.IsCancellationRequested; | |
// The compiler will generate stuff that hooks in | |
// here. We hook those methods directly into the | |
// cancellation token. | |
public void OnCompleted(Action continuation) => | |
CancellationToken.Register(continuation); | |
public void UnsafeOnCompleted(Action continuation) => | |
CancellationToken.Register(continuation); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You may not be aware of this, but legally, without a license, no one can use your code.
http://opensource.stackexchange.com/q/1720/775