Skip to content

Commit bd38ef0

Browse files
authored
Add Task.WaitAsync (#48)
1 parent bffd5c3 commit bd38ef0

6 files changed

+131
-10
lines changed

api_list.include.md

+22
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,28 @@
199199
* `Boolean Equals(ReadOnlySpan<Char>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char))))
200200

201201

202+
### Task
203+
204+
* `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken))
205+
* `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan))
206+
* `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken))
207+
208+
209+
### Task<TResult>
210+
211+
* `Task<TResult> WaitAsync<TResult>(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken))
212+
213+
214+
### Task<TResult>
215+
216+
* `Task<TResult> WaitAsync<TResult>(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken))
217+
218+
219+
### Task<TResult>
220+
221+
* `Task<TResult> WaitAsync<TResult>(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken))
222+
223+
202224
### TextReader
203225

204226
* `ValueTask<Int32> ReadAsync(Memory<Char>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken))

contributing.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ static partial class PolyfillExtensions
268268
this TextWriter target,
269269
ReadOnlySpan<char> buffer)
270270
{
271-
var array = ArrayPool<char>.Shared.Rent(buffer.Length);
271+
var pool = ArrayPool<char>.Shared;
272+
var array = pool.Rent(buffer.Length);
272273

273274
try
274275
{
@@ -277,7 +278,7 @@ static partial class PolyfillExtensions
277278
}
278279
finally
279280
{
280-
ArrayPool<char>.Shared.Return(array);
281+
pool.Return(array);
281282
}
282283
}
283284

@@ -290,7 +291,8 @@ static partial class PolyfillExtensions
290291
this TextWriter target,
291292
ReadOnlySpan<char> buffer)
292293
{
293-
var array = ArrayPool<char>.Shared.Rent(buffer.Length);
294+
var pool = ArrayPool<char>.Shared;
295+
var array = pool.Rent(buffer.Length);
294296

295297
try
296298
{
@@ -299,13 +301,13 @@ static partial class PolyfillExtensions
299301
}
300302
finally
301303
{
302-
ArrayPool<char>.Shared.Return(array);
304+
pool.Return(array);
303305
}
304306
}
305307
}
306308
#endif
307309
```
308-
<sup><a href='/src/Polyfill/PolyfillExtensions_TextWriter.cs#L1-L115' title='Snippet source file'>snippet source</a> | <a href='#snippet-PolyfillExtensions_TextWriter.cs' title='Start of snippet'>anchor</a></sup>
310+
<sup><a href='/src/Polyfill/PolyfillExtensions_TextWriter.cs#L1-L117' title='Snippet source file'>snippet source</a> | <a href='#snippet-PolyfillExtensions_TextWriter.cs' title='Start of snippet'>anchor</a></sup>
309311
<!-- endSnippet -->
310312

311313

src/Consume/Consume.cs

+12
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ async Task StreamReaderReadToEndAsync()
134134
var read = await reader.ReadToEndAsync(CancellationToken.None);
135135
}
136136

137+
void WaitAsync()
138+
{
139+
var action = () => {};
140+
var func = () => 0;
141+
new Task(action).WaitAsync(CancellationToken.None);
142+
new Task(action).WaitAsync(TimeSpan.Zero);
143+
new Task(action).WaitAsync(TimeSpan.Zero, CancellationToken.None);
144+
new Task<int>(func).WaitAsync(CancellationToken.None);
145+
new Task<int>(func).WaitAsync(TimeSpan.Zero);
146+
new Task<int>(func).WaitAsync(TimeSpan.Zero, CancellationToken.None);
147+
}
148+
137149
#if MEMORYREFERENCED
138150

139151
async Task StreamReaderReadAsync()

src/Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project>
33
<PropertyGroup>
4-
<Version>1.21.0</Version>
4+
<Version>1.22.0</Version>
55
<AssemblyVersion>1.0.0</AssemblyVersion>
66
<PackageTags>Polyfill</PackageTags>
77
<DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0
2+
3+
#pragma warning disable
4+
5+
// ReSharper disable RedundantUsingDirective
6+
// ReSharper disable PartialTypeWithSinglePart
7+
// ReSharper disable UnusedMember.Global
8+
// ReSharper disable RedundantAttributeSuffix
9+
10+
using System;
11+
using System.Reflection;
12+
using System.Threading;
13+
using System.Threading.Tasks;
14+
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
15+
16+
static partial class PolyfillExtensions
17+
{
18+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")]
19+
public static Task WaitAsync(this Task task, CancellationToken cancellationToken) =>
20+
task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken);
21+
22+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")]
23+
public static async Task WaitAsync(this Task task, TimeSpan timeout)
24+
{
25+
var cancellationSource = new CancellationTokenSource();
26+
try
27+
{
28+
await task.WaitAsync(timeout, cancellationSource.Token);
29+
}
30+
finally
31+
{
32+
cancellationSource.Cancel();
33+
cancellationSource.Dispose();
34+
}
35+
}
36+
37+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")]
38+
public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken)
39+
{
40+
var delayTask = Task.Delay(timeout, cancellationToken);
41+
var completedTask = await Task.WhenAny(task, delayTask);
42+
if (completedTask == delayTask)
43+
{
44+
throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms");
45+
}
46+
47+
await task;
48+
}
49+
50+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")]
51+
public static Task<TResult> WaitAsync<TResult>(this Task<TResult> task, CancellationToken cancellationToken) =>
52+
task.WaitAsync<TResult>(Timeout.InfiniteTimeSpan, cancellationToken);
53+
54+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")]
55+
public static async Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout)
56+
{
57+
var cancellationSource = new CancellationTokenSource();
58+
try
59+
{
60+
return await task.WaitAsync(timeout, cancellationSource.Token);
61+
}
62+
finally
63+
{
64+
cancellationSource.Cancel();
65+
cancellationSource.Dispose();
66+
}
67+
}
68+
69+
[DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")]
70+
public static async Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout, CancellationToken cancellationToken)
71+
{
72+
var delayTask = Task.Delay(timeout, cancellationToken);
73+
var completedTask = await Task.WhenAny(task, delayTask);
74+
if (completedTask == delayTask)
75+
{
76+
throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms");
77+
}
78+
79+
return await task;
80+
}
81+
}
82+
83+
#endif

src/Polyfill/PolyfillExtensions_TextWriter.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public static void Write(
7777
this TextWriter target,
7878
ReadOnlySpan<char> buffer)
7979
{
80-
var array = ArrayPool<char>.Shared.Rent(buffer.Length);
80+
var pool = ArrayPool<char>.Shared;
81+
var array = pool.Rent(buffer.Length);
8182

8283
try
8384
{
@@ -86,7 +87,7 @@ public static void Write(
8687
}
8788
finally
8889
{
89-
ArrayPool<char>.Shared.Return(array);
90+
pool.Return(array);
9091
}
9192
}
9293

@@ -99,7 +100,8 @@ public static void WriteLine(
99100
this TextWriter target,
100101
ReadOnlySpan<char> buffer)
101102
{
102-
var array = ArrayPool<char>.Shared.Rent(buffer.Length);
103+
var pool = ArrayPool<char>.Shared;
104+
var array = pool.Rent(buffer.Length);
103105

104106
try
105107
{
@@ -108,7 +110,7 @@ public static void WriteLine(
108110
}
109111
finally
110112
{
111-
ArrayPool<char>.Shared.Return(array);
113+
pool.Return(array);
112114
}
113115
}
114116
}

0 commit comments

Comments
 (0)