forked from npgsql/npgsql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWaitHandleExtensions.cs
More file actions
42 lines (37 loc) · 1.62 KB
/
WaitHandleExtensions.cs
File metadata and controls
42 lines (37 loc) · 1.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#if NETSTANDARD2_0
using System.Threading.Tasks;
// ReSharper disable once CheckNamespace
namespace System.Threading
{
// https://thomaslevesque.com/2015/06/04/async-and-cancellation-support-for-wait-handles/
static class WaitHandleExtensions
{
internal static async Task<bool> WaitOneAsync(
this WaitHandle handle, int millisecondsTimeout, CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<bool>();
using var tokenRegistration =
cancellationToken.Register(state => ((TaskCompletionSource<bool>)state!).TrySetCanceled(), tcs);
RegisteredWaitHandle? registeredHandle = null;
try
{
registeredHandle = ThreadPool.RegisterWaitForSingleObject(
handle,
(state, timedOut) => ((TaskCompletionSource<bool>)state!).TrySetResult(!timedOut),
state: tcs,
millisecondsTimeout,
executeOnlyOnce: true);
return await tcs.Task;
}
finally
{
registeredHandle?.Unregister(null);
}
}
internal static Task<bool> WaitOneAsync(this WaitHandle handle, TimeSpan timeout, CancellationToken cancellationToken = default)
=> handle.WaitOneAsync((int)timeout.TotalMilliseconds, cancellationToken);
internal static Task<bool> WaitOneAsync(this WaitHandle handle, CancellationToken cancellationToken = default)
=> handle.WaitOneAsync(Timeout.Infinite, cancellationToken);
}
}
#endif