Skip to content

Commit 3fddf24

Browse files
committed
Merge latest in
1 parent 15547dc commit 3fddf24

File tree

2 files changed

+57
-57
lines changed

2 files changed

+57
-57
lines changed

tests/StackExchange.Redis.Tests/CancellationTests.cs

Lines changed: 8 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,79 +3,30 @@
33
using System.Threading;
44
using System.Threading.Tasks;
55
using Xunit;
6-
using Xunit.Abstractions;
76

87
namespace StackExchange.Redis.Tests;
98

10-
#if !NET6_0_OR_GREATER
11-
internal static class TaskExtensions
12-
{
13-
// suboptimal polyfill version of the .NET 6+ API; I'm not recommending this for production use,
14-
// but it's good enough for tests
15-
public static Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken)
16-
{
17-
if (task.IsCompleted || !cancellationToken.CanBeCanceled) return task;
18-
return Wrap(task, cancellationToken);
19-
20-
static async Task<T> Wrap(Task<T> task, CancellationToken cancellationToken)
21-
{
22-
var tcs = new TaskCompletionSource<T>();
23-
using var reg = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
24-
_ = task.ContinueWith(t =>
25-
{
26-
if (t.IsCanceled) tcs.TrySetCanceled();
27-
else if (t.IsFaulted) tcs.TrySetException(t.Exception!);
28-
else tcs.TrySetResult(t.Result);
29-
});
30-
return await tcs.Task;
31-
}
32-
}
33-
34-
public static Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout)
35-
{
36-
if (task.IsCompleted) return task;
37-
return Wrap(task, timeout);
38-
39-
static async Task<T> Wrap(Task<T> task, TimeSpan timeout)
40-
{
41-
Task other = Task.Delay(timeout);
42-
var first = await Task.WhenAny(task, other);
43-
if (ReferenceEquals(first, other))
44-
{
45-
throw new TimeoutException();
46-
}
47-
return await task;
48-
}
49-
}
50-
}
51-
#endif
52-
539
[Collection(SharedConnectionFixture.Key)]
54-
public class CancellationTests : TestBase
10+
public class CancellationTests(ITestOutputHelper output, SharedConnectionFixture fixture) : TestBase(output, fixture)
5511
{
56-
public CancellationTests(ITestOutputHelper output, SharedConnectionFixture fixture) : base(output, fixture) { }
57-
5812
[Fact]
5913
public async Task WithCancellation_CancelledToken_ThrowsOperationCanceledException()
6014
{
61-
using var conn = Create();
15+
await using var conn = Create();
6216
var db = conn.GetDatabase();
6317

6418
using var cts = new CancellationTokenSource();
6519
cts.Cancel(); // Cancel immediately
6620

67-
await Assert.ThrowsAnyAsync<OperationCanceledException>(async () =>
68-
{
69-
await db.StringSetAsync(Me(), "value").WaitAsync(cts.Token);
70-
});
21+
await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await db.StringSetAsync(Me(), "value").WaitAsync(cts.Token));
7122
}
7223

7324
private IInternalConnectionMultiplexer Create() => Create(syncTimeout: 10_000);
7425

7526
[Fact]
7627
public async Task WithCancellation_ValidToken_OperationSucceeds()
7728
{
78-
using var conn = Create();
29+
await using var conn = Create();
7930
var db = conn.GetDatabase();
8031

8132
using var cts = new CancellationTokenSource();
@@ -89,13 +40,13 @@ public async Task WithCancellation_ValidToken_OperationSucceeds()
8940

9041
private void Pause(IDatabase db)
9142
{
92-
db.Execute("client", new object[] { "pause", ConnectionPauseMilliseconds }, CommandFlags.FireAndForget);
43+
db.Execute("client", ["pause", ConnectionPauseMilliseconds], CommandFlags.FireAndForget);
9344
}
9445

9546
[Fact]
9647
public async Task WithTimeout_ShortTimeout_Async_ThrowsOperationCanceledException()
9748
{
98-
using var conn = Create();
49+
await using var conn = Create();
9950
var db = conn.GetDatabase();
10051

10152
var watch = Stopwatch.StartNew();
@@ -122,7 +73,7 @@ public async Task WithTimeout_ShortTimeout_Async_ThrowsOperationCanceledExceptio
12273
[Fact]
12374
public async Task WithoutCancellation_OperationsWorkNormally()
12475
{
125-
using var conn = Create();
76+
await using var conn = Create();
12677
var db = conn.GetDatabase();
12778

12879
// No cancellation - should work normally
@@ -171,7 +122,7 @@ private static CancellationTokenSource CreateCts(CancelStrategy strategy)
171122
[InlineData(CancelStrategy.Manual)]
172123
public async Task CancellationDuringOperation_Async_CancelsGracefully(CancelStrategy strategy)
173124
{
174-
using var conn = Create();
125+
await using var conn = Create();
175126
var db = conn.GetDatabase();
176127

177128
var watch = Stopwatch.StartNew();
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#if !NET
2+
using System;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace StackExchange.Redis.Tests;
7+
8+
internal static class TaskExtensions
9+
{
10+
// suboptimal polyfill version of the .NET 6+ API; I'm not recommending this for production use,
11+
// but it's good enough for tests
12+
public static Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken)
13+
{
14+
if (task.IsCompleted || !cancellationToken.CanBeCanceled) return task;
15+
return Wrap(task, cancellationToken);
16+
17+
static async Task<T> Wrap(Task<T> task, CancellationToken cancellationToken)
18+
{
19+
var tcs = new TaskCompletionSource<T>();
20+
using var reg = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
21+
_ = task.ContinueWith(t =>
22+
{
23+
if (t.IsCanceled) tcs.TrySetCanceled();
24+
else if (t.IsFaulted) tcs.TrySetException(t.Exception!);
25+
else tcs.TrySetResult(t.Result);
26+
});
27+
return await tcs.Task;
28+
}
29+
}
30+
31+
public static Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout)
32+
{
33+
if (task.IsCompleted) return task;
34+
return Wrap(task, timeout);
35+
36+
static async Task<T> Wrap(Task<T> task, TimeSpan timeout)
37+
{
38+
Task other = Task.Delay(timeout);
39+
var first = await Task.WhenAny(task, other);
40+
if (ReferenceEquals(first, other))
41+
{
42+
throw new TimeoutException();
43+
}
44+
return await task;
45+
}
46+
}
47+
}
48+
49+
#endif

0 commit comments

Comments
 (0)