Skip to content

Commit 0afabb5

Browse files
Feedback
1 parent cc9d1be commit 0afabb5

File tree

4 files changed

+89
-296
lines changed

4 files changed

+89
-296
lines changed

snippets/csharp/System/ThreadStaticAttribute/Overview/Project.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net6.0</TargetFramework>
6+
<Nullable>enable</Nullable>
67
</PropertyGroup>
7-
8+
89
</Project>

snippets/csharp/System/ThreadStaticAttribute/Overview/threadsafe2a.cs

Lines changed: 37 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -2,114 +2,43 @@
22
using System;
33
using System.Threading;
44

5-
public class Example
5+
class Program
66
{
7-
[ThreadStatic] static double previous;
8-
[ThreadStatic] static double sum;
9-
[ThreadStatic] static int calls;
10-
[ThreadStatic] static bool abnormal;
11-
static int totalNumbers = 0;
12-
static CountdownEvent countdown;
13-
private static Object lockObj;
14-
Random rand;
15-
16-
public Example()
17-
{
18-
rand = new Random();
19-
lockObj = new Object();
20-
countdown = new CountdownEvent(1);
21-
}
22-
23-
public static void Main()
24-
{
25-
Example ex = new Example();
26-
Thread.CurrentThread.Name = "Main";
27-
ex.Execute();
28-
countdown.Wait();
29-
Console.WriteLine("{0:N0} random numbers were generated.", totalNumbers);
30-
}
31-
32-
private void Execute()
33-
{
34-
for (int threads = 1; threads <= 10; threads++)
35-
{
36-
Thread newThread = new Thread(new ThreadStart(this.GetRandomNumbers));
37-
countdown.AddCount();
38-
newThread.Name = threads.ToString();
39-
newThread.Start();
40-
}
41-
this.GetRandomNumbers();
42-
}
43-
44-
private void GetRandomNumbers()
45-
{
46-
// Initialize ThreadStatic fields for this thread.
47-
previous = 0.0;
48-
sum = 0.0;
49-
calls = 0;
50-
abnormal = false;
51-
52-
double result = 0.0;
53-
54-
for (int ctr = 0; ctr < 2000000; ctr++)
55-
{
56-
lock (lockObj) {
57-
result = rand.NextDouble();
58-
calls++;
59-
Interlocked.Increment(ref totalNumbers);
60-
// We should never get the same random number twice.
61-
if (result == previous) {
62-
abnormal = true;
63-
break;
64-
}
65-
else {
66-
previous = result;
67-
sum += result;
68-
}
69-
}
70-
}
71-
// get last result
72-
if (abnormal)
73-
Console.WriteLine("Result is {0} in {1}", previous, Thread.CurrentThread.Name);
74-
75-
Console.WriteLine("Thread {0} finished random number generation.", Thread.CurrentThread.Name);
76-
Console.WriteLine("Sum = {0:N4}, Mean = {1:N4}, n = {2:N0}\n", sum, sum/calls, calls);
77-
countdown.Signal();
78-
}
7+
[ThreadStatic]
8+
private static string? _requestId;
9+
10+
static void Main()
11+
{
12+
Thread thread1 = new Thread(ProcessRequest);
13+
Thread thread2 = new Thread(ProcessRequest);
14+
15+
thread1.Start("REQ-001");
16+
thread2.Start("REQ-002");
17+
18+
thread1.Join();
19+
thread2.Join();
20+
21+
Console.WriteLine("Main thread execution completed.");
22+
}
23+
24+
static void ProcessRequest(object? requestId)
25+
{
26+
// Assign the request ID to the thread-static field
27+
_requestId = requestId as string;
28+
29+
// Simulate request processing across multiple method calls
30+
PerformDatabaseOperation();
31+
PerformLogging();
32+
}
33+
34+
static void PerformDatabaseOperation()
35+
{
36+
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Processing DB operation for request {_requestId}");
37+
}
38+
39+
static void PerformLogging()
40+
{
41+
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Logging request {_requestId}");
42+
}
7943
}
80-
// The example displays output similar to the following:
81-
// Thread 1 finished random number generation.
82-
// Sum = 1,000,556.7483, Mean = 0.5003, n = 2,000,000
83-
//
84-
// Thread 6 finished random number generation.
85-
// Sum = 999,704.3865, Mean = 0.4999, n = 2,000,000
86-
//
87-
// Thread 2 finished random number generation.
88-
// Sum = 999,680.8904, Mean = 0.4998, n = 2,000,000
89-
//
90-
// Thread 10 finished random number generation.
91-
// Sum = 999,437.5132, Mean = 0.4997, n = 2,000,000
92-
//
93-
// Thread 8 finished random number generation.
94-
// Sum = 1,000,663.7789, Mean = 0.5003, n = 2,000,000
95-
//
96-
// Thread 4 finished random number generation.
97-
// Sum = 999,379.5978, Mean = 0.4997, n = 2,000,000
98-
//
99-
// Thread 5 finished random number generation.
100-
// Sum = 1,000,011.0605, Mean = 0.5000, n = 2,000,000
101-
//
102-
// Thread 9 finished random number generation.
103-
// Sum = 1,000,637.4556, Mean = 0.5003, n = 2,000,000
104-
//
105-
// Thread Main finished random number generation.
106-
// Sum = 1,000,676.2381, Mean = 0.5003, n = 2,000,000
107-
//
108-
// Thread 3 finished random number generation.
109-
// Sum = 999,951.1025, Mean = 0.5000, n = 2,000,000
110-
//
111-
// Thread 7 finished random number generation.
112-
// Sum = 1,000,844.5217, Mean = 0.5004, n = 2,000,000
113-
//
114-
// 22,000,000 random numbers were generated.
11544
// </Snippet1>

snippets/fsharp/System/ThreadStaticAttribute/Overview/threadsafe2a.fs

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,101 +2,31 @@
22
open System
33
open System.Threading
44

5-
type Example() =
5+
type ThreadLocal() =
66
[<ThreadStatic; DefaultValue>]
7-
static val mutable private previous : double
7+
static val mutable private requestId: string option
88

9-
[<ThreadStatic; DefaultValue>]
10-
static val mutable private sum : double
11-
12-
[<ThreadStatic; DefaultValue>]
13-
static val mutable private calls : int
14-
15-
[<ThreadStatic; DefaultValue>]
16-
static val mutable private abnormal : bool
17-
18-
static let mutable totalNumbers = 0
19-
static let countdown = new CountdownEvent(1)
20-
static let lockObj = obj ()
21-
let rand = Random()
22-
23-
24-
member this.Execute() =
25-
for threads = 1 to 10 do
26-
let newThread = new Thread(ThreadStart this.GetRandomNumbers)
27-
countdown.AddCount()
28-
newThread.Name <- threads.ToString()
29-
newThread.Start()
30-
this.GetRandomNumbers()
31-
countdown.Wait()
32-
printfn $"{totalNumbers:N0} random numbers were generated."
9+
static member PerformLogging() =
10+
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Logging request {ThreadLocal.requestId.Value}")
3311

34-
member _.GetRandomNumbers() =
35-
// Initialize ThreadStatic fields for this thread.
36-
Example.previous <- 0.0
37-
Example.sum <- 0.0
38-
Example.calls <- 0
39-
Example.abnormal <- false
12+
static member PerformDatabaseOperation() =
13+
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Processing DB operation for request {ThreadLocal.requestId.Value}")
4014

41-
let mutable i = 0
42-
while i < 2000000 do
43-
lock lockObj (fun () ->
44-
let result = rand.NextDouble()
45-
Example.calls <- Example.calls + 1
46-
Interlocked.Increment &totalNumbers |> ignore
47-
// We should never get the same random number twice.
48-
if result = Example.previous then
49-
Example.abnormal <- true
50-
i <- 2000001 // break
51-
else
52-
Example.previous <- result
53-
Example.sum <- Example.sum + result )
54-
i <- i + 1
55-
// get last result
56-
if Example.abnormal then
57-
printfn $"Result is {Example.previous} in {Thread.CurrentThread.Name}"
15+
static member ProcessRequest(reqId: obj) =
16+
ThreadLocal.requestId <- Some(reqId :?> string)
17+
ThreadLocal.PerformDatabaseOperation()
18+
ThreadLocal.PerformLogging()
5819

59-
printfn $"Thread {Thread.CurrentThread.Name} finished random number generation."
60-
printfn $"Sum = {Example.sum:N4}, Mean = {Example.sum / float Example.calls:N4}, n = {Example.calls:N0}\n"
61-
countdown.Signal() |> ignore
20+
[<EntryPoint>]
21+
let main _ =
22+
let thread1 = Thread(ThreadStart(fun () -> ThreadLocal.ProcessRequest("REQ-001")))
23+
let thread2 = Thread(ThreadStart(fun () -> ThreadLocal.ProcessRequest("REQ-002")))
6224

63-
let ex = Example()
64-
Thread.CurrentThread.Name <- "Main"
65-
ex.Execute()
25+
thread1.Start()
26+
thread2.Start()
27+
thread1.Join()
28+
thread2.Join()
6629

67-
// The example displays output similar to the following:
68-
// Thread 1 finished random number generation.
69-
// Sum = 1,000,556.7483, Mean = 0.5003, n = 2,000,000
70-
//
71-
// Thread 6 finished random number generation.
72-
// Sum = 999,704.3865, Mean = 0.4999, n = 2,000,000
73-
//
74-
// Thread 2 finished random number generation.
75-
// Sum = 999,680.8904, Mean = 0.4998, n = 2,000,000
76-
//
77-
// Thread 10 finished random number generation.
78-
// Sum = 999,437.5132, Mean = 0.4997, n = 2,000,000
79-
//
80-
// Thread 8 finished random number generation.
81-
// Sum = 1,000,663.7789, Mean = 0.5003, n = 2,000,000
82-
//
83-
// Thread 4 finished random number generation.
84-
// Sum = 999,379.5978, Mean = 0.4997, n = 2,000,000
85-
//
86-
// Thread 5 finished random number generation.
87-
// Sum = 1,000,011.0605, Mean = 0.5000, n = 2,000,000
88-
//
89-
// Thread 9 finished random number generation.
90-
// Sum = 1,000,637.4556, Mean = 0.5003, n = 2,000,000
91-
//
92-
// Thread Main finished random number generation.
93-
// Sum = 1,000,676.2381, Mean = 0.5003, n = 2,000,000
94-
//
95-
// Thread 3 finished random number generation.
96-
// Sum = 999,951.1025, Mean = 0.5000, n = 2,000,000
97-
//
98-
// Thread 7 finished random number generation.
99-
// Sum = 1,000,844.5217, Mean = 0.5004, n = 2,000,000
100-
//
101-
// 22,000,000 random numbers were generated.
30+
Console.WriteLine("Main thread execution completed.")
31+
0
10232
// </Snippet1>

0 commit comments

Comments
 (0)