Skip to content

Commit 2f64b3a

Browse files
committed
- call context
1 parent 0f89a18 commit 2f64b3a

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
using NUnit.Framework;
4+
5+
namespace Shuttle.Core.Threading.Tests
6+
{
7+
[TestFixture]
8+
public class CallContextFixture
9+
{
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);
25+
26+
Task.WaitAll(
27+
Task.Run(() =>
28+
{
29+
CallContext.SetData("d1", d1);
30+
new Thread(() => t10 = CallContext.GetData("d1")).Start();
31+
Task.WaitAll(
32+
Task.Run(() => t1 = CallContext.GetData("d1"))
33+
.ContinueWith(t => Task.Run(() => t11 = CallContext.GetData("d1"))),
34+
Task.Run(() => t12 = CallContext.GetData("d1")),
35+
Task.Run(() => t13 = CallContext.GetData("d1"))
36+
);
37+
}),
38+
Task.Run(() =>
39+
{
40+
CallContext.SetData("d2", d2);
41+
new Thread(() => t20 = CallContext.GetData("d2")).Start();
42+
Task.WaitAll(
43+
Task.Run(() => t2 = CallContext.GetData("d2"))
44+
.ContinueWith(t => Task.Run(() => t21 = CallContext.GetData("d2"))),
45+
Task.Run(() => t22 = CallContext.GetData("d2")),
46+
Task.Run(() => t23 = CallContext.GetData("d2"))
47+
);
48+
})
49+
);
50+
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));
56+
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));
62+
63+
Assert.Null(CallContext.GetData("d1"));
64+
Assert.Null(CallContext.GetData("d2"));
65+
}
66+
}
67+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Collections.Concurrent;
2+
using System.Threading;
3+
using Shuttle.Core.Contract;
4+
5+
namespace Shuttle.Core.Threading
6+
{
7+
// shout-out to Daniel Cazzulino: http://www.cazzulino.com/callcontext-netstandard-netcore.html
8+
public static class CallContext
9+
{
10+
private static readonly ConcurrentDictionary<string, AsyncLocal<object>> State = new ConcurrentDictionary<string, AsyncLocal<object>>();
11+
12+
public static void SetData(string name, object data)
13+
{
14+
Guard.AgainstNullOrEmptyString(name, nameof(name));
15+
16+
State.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
17+
}
18+
19+
public static object GetData(string name)
20+
{
21+
Guard.AgainstNullOrEmptyString(name, nameof(name));
22+
23+
return State.TryGetValue(name, out var data) ? data.Value : null;
24+
}
25+
26+
public static object RemoveData(string name)
27+
{
28+
Guard.AgainstNullOrEmptyString(name, nameof(name));
29+
30+
return State.TryRemove(name, out var data) ? data.Value : null;
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)