-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathTaskExtensions.cs
More file actions
73 lines (61 loc) · 1.95 KB
/
TaskExtensions.cs
File metadata and controls
73 lines (61 loc) · 1.95 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
// Polyfills for Task APIs not available on .NET Framework.
// These are test-only and not optimized for production use.
#if !NET8_0_OR_GREATER
using System.Threading;
namespace System.Threading.Tasks;
internal static class TestDownlevelTaskExtensions
{
extension(Task task)
{
public Task WaitAsync(TimeSpan timeout)
{
if (task.IsCompleted)
{
return task;
}
return WaitAsyncCore(task, timeout);
}
}
extension<T>(Task<T> task)
{
public Task<T> WaitAsync(TimeSpan timeout)
{
if (task.IsCompleted)
{
return task;
}
return WaitAsyncCoreGeneric(task, timeout);
}
}
private static async Task WaitAsyncCore(Task task, TimeSpan timeout)
{
using var cts = new CancellationTokenSource();
var delayTask = Task.Delay(timeout, cts.Token);
var completedTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
if (completedTask == task)
{
cts.Cancel();
await task.ConfigureAwait(false);
}
else
{
throw new TimeoutException();
}
}
private static async Task<T> WaitAsyncCoreGeneric<T>(Task<T> task, TimeSpan timeout)
{
using var cts = new CancellationTokenSource();
var delayTask = Task.Delay(timeout, cts.Token);
var completedTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
if (completedTask == task)
{
cts.Cancel();
return await task.ConfigureAwait(false);
}
throw new TimeoutException();
}
}
#endif