Skip to content

Commit 547054b

Browse files
author
ahotko
committed
Refactoring of Multithreading samples, added GarbageCollection sample and Thread sample
1 parent 2bf9d48 commit 547054b

File tree

6 files changed

+154
-8
lines changed

6 files changed

+154
-8
lines changed

CSharp Code Samples/CodeSamples/CodeSamples.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
<Compile Include="Constants.cs" />
6666
<Compile Include="ISampleExecute.cs" />
6767
<Compile Include="MultiThreading\BackgroundWorkerSample.cs" />
68+
<Compile Include="MultiThreading\MultithreadingSample.cs" />
69+
<Compile Include="MultiThreading\ThreadSample.cs" />
6870
<Compile Include="Patterns\Behavioral\ObserverPattern.cs" />
6971
<Compile Include="Patterns\Behavioral\StatePattern.cs" />
7072
<Compile Include="Patterns\Creational\AbstractFactoryPattern.cs" />
@@ -97,6 +99,7 @@
9799
<Compile Include="TupleDeconstruction\TupleDeconstruction.cs" />
98100
<Compile Include="UsefulClasses\Dictionaries.cs" />
99101
<Compile Include="UsefulClasses\ObjectPoolSample.cs" />
102+
<Compile Include="Useful\GarbageCollectionSample.cs" />
100103
<Compile Include="Useful\LinqSample.cs" />
101104
<Compile Include="Classes\ClassAndMethodNamesSample.cs" />
102105
</ItemGroup>

CSharp Code Samples/CodeSamples/MultiThreading/BackgroundWorkerSample.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44

55
namespace CodeSamples.MultiThreading
66
{
7-
public class BackgroundWorkerSample : SampleExecute
7+
public class BackgroundWorkerSample
88
{
99
private readonly AutoResetEvent resetEvent = new AutoResetEvent(false);
1010

11-
public override void Execute()
11+
public void Go()
1212
{
13-
Title("BackgroundWorkerSampleExecute");
14-
Section("BackgroundWorker is...");
15-
1613
BackgroundWorker backgroundWorker = new BackgroundWorker();
1714
backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
1815
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
@@ -26,7 +23,6 @@ public override void Execute()
2623
}
2724
//wait for background worker to finish; not necessary, but required for testing samples, so they execute in order
2825
resetEvent.WaitOne();
29-
Finish();
3026
}
3127

3228
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace CodeSamples.MultiThreading
2+
{
3+
public class MultithreadingSample : SampleExecute
4+
{
5+
public override void Execute()
6+
{
7+
Title("MultithreadingSample");
8+
9+
Section("BackgroundWorker is online...");
10+
var backgroundWorkerSample = new BackgroundWorkerSample();
11+
backgroundWorkerSample.Go();
12+
13+
LineBreak();
14+
15+
Section("Thread is online...");
16+
var threadSample = new ThreadSample();
17+
threadSample.Go();
18+
19+
Finish();
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Threading;
3+
4+
namespace CodeSamples.MultiThreading
5+
{
6+
internal class LaborInstructions
7+
{
8+
private readonly AutoResetEvent _syncObject;
9+
10+
public string SomeParameter { get; set; }
11+
12+
public AutoResetEvent SyncObject => _syncObject;
13+
14+
public LaborInstructions(AutoResetEvent syncObject)
15+
{
16+
_syncObject = syncObject;
17+
}
18+
}
19+
20+
internal class ThreadLabor
21+
{
22+
public void DoWork(object instructions)
23+
{
24+
var passedParametersClass = instructions as LaborInstructions;
25+
Console.WriteLine($"Doing labor... {passedParametersClass.SomeParameter} ... and waiting to complete...");
26+
Thread.Sleep(1000);
27+
passedParametersClass.SyncObject.Set();
28+
}
29+
}
30+
31+
public class ThreadSample
32+
{
33+
private readonly AutoResetEvent syncObject = new AutoResetEvent(false);
34+
35+
public void Go()
36+
{
37+
var threadLabor = new ThreadLabor();
38+
var laborInstructions = new LaborInstructions(syncObject);
39+
laborInstructions.SomeParameter = $"Current DateTime is {DateTime.Now.ToString()}";
40+
41+
Console.WriteLine("Going into thread...");
42+
var thread = new Thread(threadLabor.DoWork);
43+
thread.Priority = ThreadPriority.Highest;
44+
thread.Start(laborInstructions);
45+
syncObject.WaitOne();
46+
Console.WriteLine("done!");
47+
}
48+
}
49+
}

CSharp Code Samples/CodeSamples/Program.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ static void Main(string[] args)
108108
#endregion
109109

110110
#region Threading
111-
var backgroundWorkerSample = new BackgroundWorkerSample();
112-
backgroundWorkerSample.Execute();
111+
var multithreadingSample = new MultithreadingSample();
112+
multithreadingSample.Execute();
113113
#endregion
114114

115115
#region Equality
@@ -130,6 +130,11 @@ static void Main(string[] args)
130130
timingSample.Execute();
131131
#endregion
132132

133+
#region Garbage Collection
134+
var gcSample = new GarbageCollectionSample();
135+
gcSample.Execute();
136+
#endregion
137+
133138
Console.WriteLine();
134139
Console.WriteLine("End Code Samples");
135140

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Threading;
3+
4+
/// <summary>
5+
/// System.Runtime.GCLatencyMode.SustainedLowLatency
6+
/// https://docs.microsoft.com/en-us/dotnet/api/system.runtime.gclatencymode?view=netcore-3.1
7+
///
8+
/// Batch Disables garbage collection concurrency and reclaims
9+
/// objects in a batch call. This is the most intrusive mode.
10+
/// This mode is designed for maximum throughput at the
11+
/// expense of responsiveness.
12+
///
13+
/// Interactive Enables garbage collection concurrency and reclaims
14+
/// objects while the application is running. This is
15+
/// the default mode for garbage collection on a
16+
/// workstation and is less intrusive than Batch.
17+
/// It balances responsiveness with throughput. This
18+
/// mode is equivalent to garbage collection on a
19+
/// workstation that is concurrent.
20+
///
21+
/// LowLatency Enables garbage collection that is more conservative
22+
/// in reclaiming objects. Full collections occur only
23+
/// if the system is under memory pressure, whereas
24+
/// generation 0 and generation 1 collections might occur
25+
/// more frequently. This mode is not available for the
26+
/// server garbage collector.
27+
///
28+
/// NoGCRegion Indicates that garbage collection is suspended while
29+
/// the app is executing a critical path.
30+
/// NoGCRegion is a read-only value; that is, you cannot
31+
/// assign the NoGCRegion value to the LatencyMode property.
32+
/// You specify the no GC region latency mode by calling the
33+
/// TryStartNoGCRegion method and terminate it by calling the
34+
/// EndNoGCRegion() method.
35+
///
36+
/// SustainedLowLatency Enables garbage collection that tries to minimize latency
37+
/// over an extended period. The collector tries to perform
38+
/// only generation 0, generation 1, and concurrent
39+
/// generation 2 collections. Full blocking collections may
40+
/// still occur if the system is under memory pressure.
41+
/// </summary>
42+
43+
namespace CodeSamples.Useful
44+
{
45+
public class GarbageCollectionSample : SampleExecute
46+
{
47+
private void TurnGarbageCollectionOff()
48+
{
49+
Console.Write("Turning Garbage Collection into low latency (= off)...");
50+
System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.SustainedLowLatency;
51+
Console.WriteLine("done!");
52+
}
53+
54+
private void TurnGarbageCollectionOn()
55+
{
56+
Console.Write("Turning Garbage Collection into interactive (= on)...");
57+
System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Interactive;
58+
Console.WriteLine("done!");
59+
}
60+
61+
public override void Execute()
62+
{
63+
Title("GarbageCollectionSample");
64+
TurnGarbageCollectionOff();
65+
Thread.Sleep(1000);
66+
TurnGarbageCollectionOn();
67+
68+
Finish();
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)