Skip to content

Commit b1f4df0

Browse files
Optimize async operations with default
- Replaced `new ValueTask()` with `default` across async operations for better performance. - In `BasicTests.cs`, updated `ReadAllAsync` method calls for efficiency. - `SourceTests.cs` now uses `Assert.ThrowsAsync` for testing task cancellations. - In `Extensions.Read.cs`, renamed `index` to `count` and simplified async read logic. - Removed unnecessary cancellation checks in some async operations. - Applied `ValueTask` optimization in write extensions for consistency. - Updated project version to 8.4.1, indicating minor improvements and optimizations.
1 parent 018def4 commit b1f4df0

File tree

8 files changed

+26
-27
lines changed

8 files changed

+26
-27
lines changed

Open.ChannelExtensions.Tests/BasicTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public static async Task ReadAllAsync(int testSize)
187187
.ReadAllAsync(i =>
188188
{
189189
result.Add(i);
190-
return new ValueTask();
190+
return default;
191191
});
192192
sw.Stop();
193193

@@ -221,7 +221,7 @@ public static async Task PipeToBounded(int testSize)
221221
.ReadAllAsync(i =>
222222
{
223223
result.Add(i);
224-
return new ValueTask();
224+
return default;
225225
});
226226
sw.Stop();
227227

@@ -255,7 +255,7 @@ public static async Task PipeToUnbound(int testSize)
255255
.ReadAllAsync(i =>
256256
{
257257
result.Add(i);
258-
return new ValueTask();
258+
return default;
259259
});
260260
sw.Stop();
261261

Open.ChannelExtensions.Tests/SourceTests.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static async Task ToChannelCancelledAfterwriteStarts()
1515
catch (OperationCanceledException)
1616
{ }
1717

18-
await reader.ReadAll(_ => { });
18+
await Assert.ThrowsAsync<OperationCanceledException>(() => reader.ReadAll(_ => { }).AsTask());
1919
await Assert.ThrowsAsync<TaskCanceledException>(() => reader.Completion);
2020
}
2121

@@ -26,8 +26,7 @@ public static async Task ToChannelCancelledBeforeWriteStarts()
2626
cts.Cancel();
2727
var reader = Enumerable.Range(0, 10_000).ToChannel(10, true, cts.Token);
2828

29-
var count = await reader.ReadAll(_ => { });
30-
Assert.Equal(0, count);
29+
await Assert.ThrowsAsync<TaskCanceledException>(() => reader.ReadAll(_ => { }).AsTask());
3130
await Assert.ThrowsAsync<TaskCanceledException>(() => reader.Completion);
3231
}
3332
}

Open.ChannelExtensions/Extensions.Read.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ public static async ValueTask<List<T>> ReadBatchAsync<T>(this ChannelReader<T> r
102102
if (results.Count == max)
103103
return results;
104104

105-
cancellationToken.ThrowIfCancellationRequested();
106105
}
107106
while (await reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false));
108107
}
@@ -134,8 +133,9 @@ public static async ValueTask<long> ReadUntilCancelledAsync<T>(this ChannelReade
134133
if (deferredExecution)
135134
await Task.Yield();
136135

137-
long index = 0;
136+
long count = 0;
138137

138+
// Note: if the channel has complete with an OperationCanceledException, this will throw when waiting to read.
139139
if (cancellationToken.CanBeCanceled)
140140
{
141141
do
@@ -144,7 +144,7 @@ public static async ValueTask<long> ReadUntilCancelledAsync<T>(this ChannelReade
144144
!cancellationToken.IsCancellationRequested
145145
&& reader.TryRead(out T? item))
146146
{
147-
await receiver(item, index++).ConfigureAwait(false);
147+
await receiver(item, count++).ConfigureAwait(false);
148148
}
149149
}
150150
while (
@@ -157,13 +157,13 @@ public static async ValueTask<long> ReadUntilCancelledAsync<T>(this ChannelReade
157157
{
158158
while (reader.TryRead(out T? item))
159159
{
160-
await receiver(item, index++).ConfigureAwait(false);
160+
await receiver(item, count++).ConfigureAwait(false);
161161
}
162162
}
163-
while (await reader.WaitToReadOrCancelAsync(cancellationToken).ConfigureAwait(false));
163+
while (await reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false));
164164
}
165165

166-
return index;
166+
return count;
167167
}
168168

169169
/// <summary>
@@ -250,7 +250,7 @@ public static ValueTask<long> ReadUntilCancelled<T>(this ChannelReader<T> reader
250250
(e, i) =>
251251
{
252252
receiver(e, i);
253-
return new ValueTask();
253+
return default;
254254
},
255255
deferredExecution);
256256

@@ -297,7 +297,7 @@ public static ValueTask<long> ReadUntilCancelled<T>(this ChannelReader<T> reader
297297
(e, _) =>
298298
{
299299
receiver(e);
300-
return new ValueTask();
300+
return default;
301301
},
302302
deferredExecution);
303303

@@ -356,7 +356,7 @@ public static ValueTask ReadAllAsEnumerables<T>(this ChannelReader<T> reader,
356356
e =>
357357
{
358358
receiver(e);
359-
return new ValueTask();
359+
return default;
360360
},
361361
deferredExecution,
362362
cancellationToken);
@@ -396,7 +396,7 @@ public static async ValueTask ReadAllAsEnumerablesAsync<T>(this ChannelReader<T>
396396
return;
397397
}
398398

399-
while (await reader.WaitToReadOrCancelAsync(cancellationToken).ConfigureAwait(false))
399+
while (await reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
400400
{
401401
await receiver(reader.ReadAvailable(cancellationToken)).ConfigureAwait(false);
402402
}
@@ -775,7 +775,7 @@ public static ValueTask<long> ReadAll<T>(this ChannelReader<T> reader,
775775
.ReadAllAsync((e, i) =>
776776
{
777777
receiver(e, i);
778-
return new ValueTask();
778+
return default;
779779
},
780780
deferredExecution,
781781
cancellationToken);
@@ -894,7 +894,7 @@ public static ValueTask<long> ReadAll<T>(this ChannelReader<T> reader,
894894
(e, _) =>
895895
{
896896
receiver(e);
897-
return new ValueTask();
897+
return default;
898898
},
899899
deferredExecution,
900900
cancellationToken);

Open.ChannelExtensions/Extensions.ReadConcurrently.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public static Task<long> ReadAllConcurrently<T>(this ChannelReader<T> reader,
177177
e =>
178178
{
179179
receiver(e);
180-
return new ValueTask();
180+
return default;
181181
},
182182
cancellationToken);
183183

@@ -321,7 +321,7 @@ public static Task ReadAllConcurrentlyAsEnumerables<T>(this ChannelReader<T> rea
321321
e =>
322322
{
323323
receiver(e);
324-
return new ValueTask();
324+
return default;
325325
},
326326
cancellationToken);
327327
}

Open.ChannelExtensions/Extensions.Write.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ await target
3535
.ConfigureAwait(false);
3636

3737
long count = 0;
38-
var next = new ValueTask();
38+
ValueTask next = default;
3939
foreach (ValueTask<T> e in source)
4040
{
4141
T? value = await e.ConfigureAwait(false);
@@ -340,7 +340,7 @@ await target
340340
.ConfigureAwait(false);
341341

342342
long count = 0;
343-
var next = new ValueTask();
343+
ValueTask next = default;
344344
await foreach (T? value in source)
345345
{
346346
await next.ConfigureAwait(false);

Open.ChannelExtensions/Extensions.WriteConcurrently.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ async Task<long> WriteAllAsyncCore()
7878
{
7979
await shouldWait.ConfigureAwait(false);
8080
long count = 0;
81-
var next = new ValueTask();
81+
ValueTask next = default;
8282
bool potentiallyCancelled = true; // if it completed and actually returned false, no need to bubble the cancellation since it actually completed.
8383
while (!errorToken.IsCancellationRequested
8484
&& !cancellationToken.IsCancellationRequested
@@ -88,7 +88,7 @@ async Task<long> WriteAllAsyncCore()
8888
await next.ConfigureAwait(false);
8989
count++;
9090
next = target.TryWrite(value) // do this to avoid unnecessary early cancel.
91-
? new ValueTask()
91+
? default
9292
: target.WriteAsync(value, cancellationToken);
9393
}
9494
await next.ConfigureAwait(false);

Open.ChannelExtensions/Extensions._.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static async ValueTask ThrowChannelClosedExceptionIfFalse(ValueTask<bool> write,
6565
internal static ValueTask CancelAsync(this CancellationTokenSource source)
6666
{
6767
source.Cancel();
68-
return new ValueTask();
68+
return default;
6969
}
7070
#endif
7171

@@ -174,7 +174,7 @@ public static ValueTask WaitToWriteAndThrowIfClosedAsync<T>(this ChannelWriter<T
174174
return ThrowChannelClosedExceptionIfFalse(waitForWrite, ifClosedMessage);
175175

176176
if (waitForWrite.Result)
177-
return new ValueTask();
177+
return default;
178178

179179
if (string.IsNullOrWhiteSpace(ifClosedMessage)) throw new ChannelClosedException();
180180
throw new ChannelClosedException(ifClosedMessage);

Open.ChannelExtensions/Open.ChannelExtensions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<RepositoryType>git</RepositoryType>
2323
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
2424
<GenerateDocumentationFile>true</GenerateDocumentationFile>
25-
<Version>8.4.0</Version>
25+
<Version>8.4.1</Version>
2626
<PackageReleaseNotes>Added .Merge, .PipeAsync, and .PropagateCompletion extensions.</PackageReleaseNotes>
2727
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2828
<PublishRepositoryUrl>true</PublishRepositoryUrl>

0 commit comments

Comments
 (0)