Skip to content

Commit 68c21ae

Browse files
committed
Implemented unified / async-only / nullable.
1 parent 640d76a commit 68c21ae

36 files changed

Lines changed: 466 additions & 673 deletions

Shuttle.Core.Threading.Tests/AmbientContextFixture.cs

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,65 @@
22
using System.Threading.Tasks;
33
using NUnit.Framework;
44

5-
namespace Shuttle.Core.Threading.Tests
5+
namespace Shuttle.Core.Threading.Tests;
6+
7+
[TestFixture]
8+
public class AmbientContextFixture
69
{
7-
[TestFixture]
8-
public class AmbientContextFixture
10+
[Test]
11+
public void Should_be_able_to_flow_data()
912
{
10-
[Test]
11-
public void Should_be_able_to_flow_data()
12-
{
13-
var d1 = new object();
14-
var t1 = default(object);
15-
var t10 = default(object);
16-
var t11 = default(object);
17-
var t12 = default(object);
18-
var t13 = default(object);
19-
var d2 = new object();
20-
var t2 = default(object);
21-
var t20 = default(object);
22-
var t21 = default(object);
23-
var t22 = default(object);
24-
var t23 = default(object);
13+
var d1 = new object();
14+
var t1 = default(object);
15+
var t10 = default(object);
16+
var t11 = default(object);
17+
var t12 = default(object);
18+
var t13 = default(object);
19+
var d2 = new object();
20+
var t2 = default(object);
21+
var t20 = default(object);
22+
var t21 = default(object);
23+
var t22 = default(object);
24+
var t23 = default(object);
2525

26-
Task.WaitAll(
27-
Task.Run(() =>
28-
{
29-
AmbientContext.SetData("d1", d1);
30-
new Thread(() => t10 = AmbientContext.GetData("d1")).Start();
31-
Task.WaitAll(
32-
Task.Run(() => t1 = AmbientContext.GetData("d1"))
33-
.ContinueWith(t => Task.Run(() => t11 = AmbientContext.GetData("d1"))),
34-
Task.Run(() => t12 = AmbientContext.GetData("d1")),
35-
Task.Run(() => t13 = AmbientContext.GetData("d1"))
36-
);
37-
}),
38-
Task.Run(() =>
39-
{
40-
AmbientContext.SetData("d2", d2);
41-
new Thread(() => t20 = AmbientContext.GetData("d2")).Start();
42-
Task.WaitAll(
43-
Task.Run(() => t2 = AmbientContext.GetData("d2"))
44-
.ContinueWith(t => Task.Run(() => t21 = AmbientContext.GetData("d2"))),
45-
Task.Run(() => t22 = AmbientContext.GetData("d2")),
46-
Task.Run(() => t23 = AmbientContext.GetData("d2"))
47-
);
48-
})
49-
);
26+
Task.WaitAll(
27+
Task.Run(() =>
28+
{
29+
AmbientContext.SetData("d1", d1);
30+
new Thread(() => t10 = AmbientContext.GetData("d1")).Start();
31+
Task.WaitAll(
32+
Task.Run(() => t1 = AmbientContext.GetData("d1"))
33+
.ContinueWith(t => Task.Run(() => t11 = AmbientContext.GetData("d1"))),
34+
Task.Run(() => t12 = AmbientContext.GetData("d1")),
35+
Task.Run(() => t13 = AmbientContext.GetData("d1"))
36+
);
37+
}),
38+
Task.Run(() =>
39+
{
40+
AmbientContext.SetData("d2", d2);
41+
new Thread(() => t20 = AmbientContext.GetData("d2")).Start();
42+
Task.WaitAll(
43+
Task.Run(() => t2 = AmbientContext.GetData("d2"))
44+
.ContinueWith(t => Task.Run(() => t21 = AmbientContext.GetData("d2"))),
45+
Task.Run(() => t22 = AmbientContext.GetData("d2")),
46+
Task.Run(() => t23 = AmbientContext.GetData("d2"))
47+
);
48+
})
49+
);
5050

51-
Assert.That(d1, Is.SameAs(t1));
52-
Assert.That(d1, Is.SameAs(t10));
53-
Assert.That(d1, Is.SameAs(t11));
54-
Assert.That(d1, Is.SameAs(t12));
55-
Assert.That(d1, Is.SameAs(t13));
51+
Assert.That(d1, Is.SameAs(t1));
52+
Assert.That(d1, Is.SameAs(t10));
53+
Assert.That(d1, Is.SameAs(t11));
54+
Assert.That(d1, Is.SameAs(t12));
55+
Assert.That(d1, Is.SameAs(t13));
5656

57-
Assert.That(d2, Is.SameAs(t2));
58-
Assert.That(d2, Is.SameAs(t20));
59-
Assert.That(d2, Is.SameAs(t21));
60-
Assert.That(d2, Is.SameAs(t22));
61-
Assert.That(d2, Is.SameAs(t23));
57+
Assert.That(d2, Is.SameAs(t2));
58+
Assert.That(d2, Is.SameAs(t20));
59+
Assert.That(d2, Is.SameAs(t21));
60+
Assert.That(d2, Is.SameAs(t22));
61+
Assert.That(d2, Is.SameAs(t23));
6262

63-
Assert.Null(AmbientContext.GetData("d1"));
64-
Assert.Null(AmbientContext.GetData("d2"));
65-
}
63+
Assert.That(AmbientContext.GetData("d1"), Is.Null);
64+
Assert.That(AmbientContext.GetData("d2"), Is.Null);
6665
}
6766
}

Shuttle.Core.Threading.Tests/MockProcessor.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,12 @@ public class MockProcessor : IProcessor
88
{
99
private readonly TimeSpan _executionDuration;
1010

11-
public int ExecutionCount { get; private set; }
12-
1311
public MockProcessor(TimeSpan executionDuration)
1412
{
1513
_executionDuration = executionDuration;
1614
}
1715

18-
public void Execute(CancellationToken cancellationToken)
19-
{
20-
ExecuteAsync(cancellationToken).GetAwaiter().GetResult();
21-
}
16+
public int ExecutionCount { get; private set; }
2217

2318
public async Task ExecuteAsync(CancellationToken cancellationToken)
2419
{

Shuttle.Core.Threading.Tests/ProcessorThreadFixture.cs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,14 @@ namespace Shuttle.Core.Threading.Tests;
77

88
public class ProcessorThreadFixture
99
{
10-
[Test]
11-
public void Should_be_able_to_execute_processor_thread()
12-
{
13-
Should_be_able_to_execute_processor_thread_async(true).GetAwaiter().GetResult();
14-
}
15-
1610
[Test]
1711
public async Task Should_be_able_to_execute_processor_thread_async()
18-
{
19-
await Should_be_able_to_execute_processor_thread_async(false);
20-
}
21-
22-
private async Task Should_be_able_to_execute_processor_thread_async(bool sync)
2312
{
2413
const int minimumExecutionCount = 5;
2514

2615
var executionDuration = TimeSpan.FromMilliseconds(200);
2716
var mockProcessor = new MockProcessor(executionDuration);
28-
var processorThread = new ProcessorThread("thread", mockProcessor, new ProcessorThreadOptions());
17+
var processorThread = new ProcessorThread("thread", mockProcessor, new());
2918
var cancellationTokenSource = new CancellationTokenSource();
3019
var cancellationToken = cancellationTokenSource.Token;
3120

@@ -51,7 +40,7 @@ private async Task Should_be_able_to_execute_processor_thread_async(bool sync)
5140

5241
processorThread.ProcessorThreadStopped += (sender, args) =>
5342
{
54-
Console.WriteLine($@"{DateTime.Now:O} - [ProcessorThreadStopped] : name = '{args.Name}' / execution count = {((MockProcessor)((ProcessorThread)sender).Processor).ExecutionCount} / managed thread id = {args.ManagedThreadId} / aborted = '{args.Aborted}'");
43+
Console.WriteLine($@"{DateTime.Now:O} - [ProcessorThreadStopped] : name = '{args.Name}' / execution count = {((MockProcessor)((ProcessorThread)sender).Processor).ExecutionCount} / managed thread id = {args.ManagedThreadId}");
5544
};
5645

5746
processorThread.ProcessorThreadStopping += (sender, args) =>
@@ -64,14 +53,7 @@ private async Task Should_be_able_to_execute_processor_thread_async(bool sync)
6453
Console.WriteLine($@"{DateTime.Now:O} - [ProcessorThreadOperationCanceled] : name = '{args.Name}' / execution count = {((MockProcessor)((ProcessorThread)sender).Processor).ExecutionCount} / managed thread id = {args.ManagedThreadId}");
6554
};
6655

67-
if (sync)
68-
{
69-
processorThread.Start();
70-
}
71-
else
72-
{
73-
await processorThread.StartAsync();
74-
}
56+
await processorThread.StartAsync();
7557

7658
var timeout = DateTime.Now.AddSeconds(500);
7759
var timedOut = false;
@@ -85,7 +67,7 @@ private async Task Should_be_able_to_execute_processor_thread_async(bool sync)
8567

8668
cancellationTokenSource.Cancel();
8769

88-
processorThread.Stop();
70+
await processorThread.StopAsync();
8971

9072
Assert.That(timedOut, Is.False, $"[TIMEOUT] : Did not complete {minimumExecutionCount} executions before {timeout:O}");
9173
}

Shuttle.Core.Threading.Tests/ProcessorThreadPoolFixture.cs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
1-
using NUnit.Framework;
2-
using System.Threading.Tasks;
3-
using System.Threading;
4-
using System;
1+
using System;
52
using System.Linq;
3+
using System.Threading;
4+
using System.Threading.Tasks;
65
using Moq;
6+
using NUnit.Framework;
77

88
namespace Shuttle.Core.Threading.Tests;
99

1010
public class ProcessorThreadPoolFixture
1111
{
12-
[Test]
13-
public void Should_be_able_to_execute_processor_thread_pool()
14-
{
15-
Should_be_able_to_execute_processor_thread_pool_async(true).GetAwaiter().GetResult();
16-
}
17-
1812
[Test]
1913
public async Task Should_be_able_to_execute_processor_thread_pool_async()
20-
{
21-
await Should_be_able_to_execute_processor_thread_pool_async(false);
22-
}
23-
24-
private async Task Should_be_able_to_execute_processor_thread_pool_async(bool sync)
2514
{
2615
const int minimumExecutionCount = 5;
2716

@@ -32,9 +21,9 @@ private async Task Should_be_able_to_execute_processor_thread_pool_async(bool sy
3221

3322
processorFactory.Setup(m => m.Create()).Returns(() => new MockProcessor(executionDuration));
3423

35-
var processorThreadPool = new ProcessorThreadPool("thread-pool", 5, processorFactory.Object, new ProcessorThreadOptions());
24+
var processorThreadPool = new ProcessorThreadPool("thread-pool", 5, processorFactory.Object, new());
3625

37-
processorThreadPool.ProcessorThreadCreated += (sender, args) =>
26+
processorThreadPool.ProcessorThreadCreated += (_, args) =>
3827
{
3928
args.ProcessorThread.ProcessorException += (sender, args) =>
4029
{
@@ -58,7 +47,7 @@ private async Task Should_be_able_to_execute_processor_thread_pool_async(bool sy
5847

5948
args.ProcessorThread.ProcessorThreadStopped += (sender, args) =>
6049
{
61-
Console.WriteLine($@"{DateTime.Now:O} - [ProcessorThreadStopped] : name = '{args.Name}' / execution count = {((MockProcessor)((ProcessorThread)sender).Processor).ExecutionCount} / managed thread id = {args.ManagedThreadId} / aborted = '{args.Aborted}'");
50+
Console.WriteLine($@"{DateTime.Now:O} - [ProcessorThreadStopped] : name = '{args.Name}' / execution count = {((MockProcessor)((ProcessorThread)sender).Processor).ExecutionCount} / managed thread id = {args.ManagedThreadId}");
6251
};
6352

6453
args.ProcessorThread.ProcessorThreadStopping += (sender, args) =>
@@ -72,14 +61,7 @@ private async Task Should_be_able_to_execute_processor_thread_pool_async(bool sy
7261
};
7362
};
7463

75-
if (sync)
76-
{
77-
processorThreadPool.Start();
78-
}
79-
else
80-
{
81-
await processorThreadPool.StartAsync();
82-
}
64+
await processorThreadPool.StartAsync();
8365

8466
var timeout = DateTime.Now.AddSeconds(5);
8567
var timedOut = false;
@@ -93,7 +75,7 @@ private async Task Should_be_able_to_execute_processor_thread_pool_async(bool sy
9375

9476
cancellationTokenSource.Cancel();
9577

96-
processorThreadPool.Stop();
78+
await processorThreadPool.StopAsync();
9779

9880
Assert.That(timedOut, Is.False, $"[TIMEOUT] : Did not complete {minimumExecutionCount} executions before {timeout:O}");
9981
}

Shuttle.Core.Threading.Tests/SharedCancellationTokenSourceFixture.cs

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,59 +5,60 @@
55
using System.Threading.Tasks;
66
using NUnit.Framework;
77

8-
namespace Shuttle.Core.Threading.Tests
8+
namespace Shuttle.Core.Threading.Tests;
9+
10+
[TestFixture]
11+
public class SharedCancellationTokenSourceFixture
912
{
10-
[TestFixture]
11-
public class SharedCancellationTokenSourceFixture
12-
{
13-
private static readonly Random Random = new Random(DateTime.Now.Millisecond);
13+
private static readonly Random Random = new(DateTime.Now.Millisecond);
1414

15-
[Test]
16-
public void Should_be_able_to_shared_cancellation_token_source_entries()
15+
[Test]
16+
public void Should_be_able_to_shared_cancellation_token_source_entries()
17+
{
18+
using (var cancellationTokenSource = new DefaultCancellationTokenSource())
1719
{
18-
using (var cancellationTokenSource = new DefaultCancellationTokenSource())
19-
{
20-
Assert.That(cancellationTokenSource.Get(), Is.SameAs(cancellationTokenSource.Get()));
21-
22-
var tasks = new List<Task>
23-
{
24-
Task.Run(() => Spin("A", cancellationTokenSource.Get().Token)),
25-
Task.Run(() => Spin("B", cancellationTokenSource.Get().Token)),
26-
Task.Run(() => Spin("C", cancellationTokenSource.Get().Token)),
27-
Task.Run(() => Spin("D", cancellationTokenSource.Get().Token))
28-
};
20+
Assert.That(cancellationTokenSource.Get(), Is.SameAs(cancellationTokenSource.Get()));
2921

30-
// wait for all the tasks to start
31-
while (tasks.Any(task => task.Status != TaskStatus.Running))
32-
{
33-
Thread.Sleep(100);
34-
}
22+
var cancellationToken = cancellationTokenSource.Get().Token;
3523

36-
cancellationTokenSource.Get().Cancel();
24+
var tasks = new List<Task>
25+
{
26+
Task.Run(() => Spin("A", cancellationToken)),
27+
Task.Run(() => Spin("B", cancellationToken)),
28+
Task.Run(() => Spin("C", cancellationToken)),
29+
Task.Run(() => Spin("D", cancellationToken))
30+
};
3731

38-
Task.WaitAll(tasks.ToArray());
32+
// wait for all the tasks to start
33+
while (tasks.Any(task => task.Status != TaskStatus.Running))
34+
{
35+
Thread.Sleep(100);
3936
}
40-
}
4137

42-
private void Spin(string name, CancellationToken cancellationToken)
43-
{
44-
Log($@"[starting] : {name}");
38+
cancellationTokenSource.Get().Cancel();
4539

46-
while (!cancellationToken.IsCancellationRequested)
47-
{
48-
var timeout = Random.Next(5, 20) * 100;
40+
Task.WaitAll(tasks.ToArray());
41+
}
42+
}
4943

50-
Log($@"[sleeping] : {name} / timeout = {timeout}");
44+
private void Spin(string name, CancellationToken cancellationToken)
45+
{
46+
Log($@"[starting] : {name}");
5147

52-
Thread.Sleep(timeout);
53-
}
48+
while (!cancellationToken.IsCancellationRequested)
49+
{
50+
var timeout = Random.Next(5, 20) * 100;
5451

55-
Log($@"[ending] : {name}");
56-
}
52+
Log($@"[sleeping] : {name} / timeout = {timeout}");
5753

58-
private void Log(string message)
59-
{
60-
Console.WriteLine($@"{DateTime.Now:O} - {message}");
54+
Thread.Sleep(timeout);
6155
}
56+
57+
Log($@"[ending] : {name}");
58+
}
59+
60+
private void Log(string message)
61+
{
62+
Console.WriteLine($@"{DateTime.Now:O} - {message}");
6263
}
6364
}

Shuttle.Core.Threading.Tests/Shuttle.Core.Threading.Tests.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
9-
<PackageReference Include="Moq" Version="4.20.70" />
10-
<PackageReference Include="NUnit" Version="3.14.0" />
11-
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
9+
<PackageReference Include="Moq" Version="4.20.72" />
10+
<PackageReference Include="NUnit" Version="4.2.2" />
11+
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
1212
</ItemGroup>
1313

1414
<ItemGroup>

0 commit comments

Comments
 (0)