|
4 | 4 | using Azure.Core.Pipeline; |
5 | 5 | using NUnit.Framework; |
6 | 6 | using System; |
7 | | -using System.Collections.Concurrent; |
8 | 7 | using System.Threading; |
9 | 8 | using System.Threading.Tasks; |
10 | 9 |
|
11 | 10 | namespace Azure.Core.Tests |
12 | 11 | { |
13 | 12 | public class TaskExtensionsTest |
14 | 13 | { |
15 | | - [Test] |
16 | | - public void TaskExtensions_TaskEnsureCompleted() |
17 | | - { |
18 | | - var task = Task.CompletedTask; |
19 | | - task.EnsureCompleted(); |
20 | | - } |
21 | | - |
22 | | - [Test] |
23 | | - public void TaskExtensions_TaskOfTEnsureCompleted() |
24 | | - { |
25 | | - var task = Task.FromResult(42); |
26 | | - Assert.AreEqual(42, task.EnsureCompleted()); |
27 | | - } |
28 | | - |
29 | | - [Test] |
30 | | - public void TaskExtensions_ValueTaskEnsureCompleted() |
31 | | - { |
32 | | - var task = new ValueTask(); |
33 | | - task.EnsureCompleted(); |
34 | | - } |
35 | | - |
36 | | - [Test] |
37 | | - public void TaskExtensions_ValueTaskOfTEnsureCompleted() |
38 | | - { |
39 | | - var task = new ValueTask<int>(42); |
40 | | - Assert.AreEqual(42, task.EnsureCompleted()); |
41 | | - } |
42 | | - |
43 | | - [Test] |
44 | | - public async Task TaskExtensions_TaskEnsureCompleted_NotCompletedNoSyncContext() |
45 | | - { |
46 | | - var tcs = new TaskCompletionSource<int>(); |
47 | | - Task task = tcs.Task; |
48 | | -#if DEBUG |
49 | | - Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); |
50 | | - await Task.CompletedTask; |
51 | | -#else |
52 | | - Task runningTask = Task.Run(() => task.EnsureCompleted()); |
53 | | - Assert.IsFalse(runningTask.IsCompleted); |
54 | | - tcs.SetResult(0); |
55 | | - await runningTask; |
56 | | -#endif |
57 | | - } |
58 | | - |
59 | | - [Test] |
60 | | - public async Task TaskExtensions_TaskOfTEnsureCompleted_NotCompletedNoSyncContext() |
61 | | - { |
62 | | - var tcs = new TaskCompletionSource<int>(); |
63 | | -#if DEBUG |
64 | | - Assert.Catch<InvalidOperationException>(() => tcs.Task.EnsureCompleted()); |
65 | | - await Task.CompletedTask; |
66 | | -#else |
67 | | - Task<int> runningTask = Task.Run(() => tcs.Task.EnsureCompleted()); |
68 | | - Assert.IsFalse(runningTask.IsCompleted); |
69 | | - tcs.SetResult(42); |
70 | | - Assert.AreEqual(42, await runningTask); |
71 | | -#endif |
72 | | - } |
73 | | - |
74 | | - [Test] |
75 | | - public async Task TaskExtensions_ValueTaskEnsureCompleted_NotCompletedNoSyncContext() |
76 | | - { |
77 | | - var tcs = new TaskCompletionSource<int>(); |
78 | | - ValueTask task = new ValueTask(tcs.Task); |
79 | | -#if DEBUG |
80 | | - Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); |
81 | | - await Task.CompletedTask; |
82 | | -#else |
83 | | - Task runningTask = Task.Run(() => task.EnsureCompleted()); |
84 | | - Assert.IsFalse(runningTask.IsCompleted); |
85 | | - tcs.SetResult(0); |
86 | | - await runningTask; |
87 | | -#endif |
88 | | - } |
89 | | - |
90 | | - [Test] |
91 | | - public async Task TaskExtensions_ValueTaskOfTEnsureCompleted_NotCompletedNoSyncContext() |
92 | | - { |
93 | | - var tcs = new TaskCompletionSource<int>(); |
94 | | - ValueTask<int> task = new ValueTask<int>(tcs.Task); |
95 | | -#if DEBUG |
96 | | - Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); |
97 | | - await Task.CompletedTask; |
98 | | -#else |
99 | | - Task<int> runningTask = Task.Run(() => task.EnsureCompleted()); |
100 | | - Assert.IsFalse(runningTask.IsCompleted); |
101 | | - tcs.SetResult(42); |
102 | | - Assert.AreEqual(42, await runningTask); |
103 | | -#endif |
104 | | - } |
105 | | - |
106 | | - [Test] |
107 | | - public void TaskExtensions_TaskEnsureCompleted_NotCompletedInSyncContext() |
108 | | - { |
109 | | - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); |
110 | | - var tcs = new TaskCompletionSource<int>(); |
111 | | - Task task = tcs.Task; |
112 | | - |
113 | | - syncContext.Post(t => { Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); }, null); |
114 | | - } |
115 | | - |
116 | | - [Test] |
117 | | - public void TaskExtensions_TaskOfTEnsureCompleted_NotCompletedInSyncContext() |
118 | | - { |
119 | | - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); |
120 | | - var tcs = new TaskCompletionSource<int>(); |
121 | | - |
122 | | - syncContext.Post(t => { Assert.Catch<InvalidOperationException>(() => tcs.Task.EnsureCompleted()); }, null); |
123 | | - } |
124 | | - |
125 | | - [Test] |
126 | | - public void TaskExtensions_ValueTaskEnsureCompleted_NotCompletedInSyncContext() |
127 | | - { |
128 | | - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); |
129 | | - var tcs = new TaskCompletionSource<int>(); |
130 | | - ValueTask task = new ValueTask(tcs.Task); |
131 | | - |
132 | | - syncContext.Post(t => { Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); }, null); |
133 | | - } |
134 | | - |
135 | | - [Test] |
136 | | - public void TaskExtensions_ValueTaskOfTEnsureCompleted_NotCompletedInSyncContext() |
137 | | - { |
138 | | - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); |
139 | | - var tcs = new TaskCompletionSource<int>(); |
140 | | - var task = new ValueTask<int>(tcs.Task); |
141 | | - |
142 | | - syncContext.Post(t => { Assert.Catch<InvalidOperationException>(() => task.EnsureCompleted()); }, null); |
143 | | - } |
144 | | - |
145 | 14 | [Test] |
146 | 15 | public void TaskExtensions_TaskWithCancellationDefault() |
147 | 16 | { |
@@ -323,55 +192,5 @@ public void TaskExtensions_ValueTaskWithCancellationFailedAfterContinuationSched |
323 | 192 | Assert.AreEqual(true, awaiter.IsCompleted); |
324 | 193 | Assert.Catch<OperationCanceledException>(() => awaiter.GetResult(), "Error"); |
325 | 194 | } |
326 | | - |
327 | | - private sealed class SingleThreadedSynchronizationContext : SynchronizationContext, IDisposable |
328 | | - { |
329 | | - private readonly Task _task; |
330 | | - private readonly BlockingCollection<Action> _queue; |
331 | | - private readonly ConcurrentQueue<Exception> _exceptions; |
332 | | - |
333 | | - public SingleThreadedSynchronizationContext() |
334 | | - { |
335 | | - _queue = new BlockingCollection<Action>(); |
336 | | - _exceptions = new ConcurrentQueue<Exception>(); |
337 | | - _task = Task.Run(RunLoop); |
338 | | - } |
339 | | - |
340 | | - private void RunLoop() |
341 | | - { |
342 | | - try |
343 | | - { |
344 | | - SetSynchronizationContext(this); |
345 | | - while (!_queue.IsCompleted) |
346 | | - { |
347 | | - Action action = _queue.Take(); |
348 | | - try |
349 | | - { |
350 | | - action(); |
351 | | - } |
352 | | - catch (Exception e) |
353 | | - { |
354 | | - _exceptions.Enqueue(e); |
355 | | - } |
356 | | - } |
357 | | - } |
358 | | - catch (InvalidOperationException) { } |
359 | | - catch (OperationCanceledException) { } |
360 | | - finally |
361 | | - { |
362 | | - SetSynchronizationContext(null); |
363 | | - } |
364 | | - } |
365 | | - |
366 | | - public override void Post(SendOrPostCallback d, object state) => _queue.Add(() => d(state)); |
367 | | - |
368 | | - public void Dispose() |
369 | | - { |
370 | | - _queue.CompleteAdding(); |
371 | | - _task.Wait(); |
372 | | - } |
373 | | - |
374 | | - public AggregateException Exceptions => new AggregateException(_exceptions); |
375 | | - } |
376 | 195 | } |
377 | 196 | } |
0 commit comments