Attempted to switch to us Parralel.For() but failed since Console is static and cannot support multithreaded redirection.
MODIFY
src/Chapter20.Tests/Listing20.01.Tests.cs
src/Chapter20.Tests/Listing20.01.Tests.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Text.RegularExpressions;
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_01.Tests
{
[TestClass]
public class ProgramTests
{
- public static void TestUnsychronizedIncrementDecrement(Action action)
+ public static bool IsIncrementDecrementSynchronized(Action<string[]> action)
{
- string expected = @"Count = *";
+ string expected = $"Increment and decrementing \\d* times...{Environment.NewLine}Count = (?<Count>\\d*)";
+ bool synchronized = true;
- string output = "";
+ CancellationTokenSource cancellationtokenSource
+ = new CancellationTokenSource();
+
+ // Try multiple times, increasing the increment/decrement iterations, just in case there is a fluke
+ ParallelOptions options = new ParallelOptions();
+ options.CancellationToken = cancellationtokenSource.Token;
+ Program.CancellationToken = cancellationtokenSource.Token;
- // Try 3 times just in case there is a fluke
- for (int i = 0; i < 3; i++)
+ try
+ {
+ Parallel.For(5, 9, options, i =>
{
- output = IntelliTect.TestTools.Console.ConsoleAssert.ExpectLike(expected,
+ string output = "";
+ string[] count = { (2 * Math.Pow(10, i)).ToString() };
+
+ output = IntelliTect.TestTools.Console.ConsoleAssert.Execute("",
() =>
{
- action();
+ action(count);
});
- if (output != "Count = 0") break;
+ Console.WriteLine(output);
+ MatchCollection matches = Regex.Matches(output, expected, System.Text.RegularExpressions.RegexOptions.Multiline);
+ if(matches.Count > 0 && matches[0].Success)
+ {
+ string result = matches[0].Groups["Count"].Value;
+ if (result != "0")
+ {
+ synchronized = false; // No synchronization required for bool
+ cancellationtokenSource.Cancel();
}
-
- Assert.AreNotEqual<string>("Count = 0", output);
+ }
+ });
+ }
+ catch(OperationCanceledException){ }
+ catch(AggregateException exception)
+ {
+ foreach (Exception innerException in exception.Flatten().InnerExceptions)
+ {
+ if (!(innerException is OperationCanceledException)){}
+ else
+ {
+ System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(
+ exception.InnerException).Throw();
+ }
+ }
+ }
+ return synchronized;
}
[TestMethod]
public void UnsynchronizedIncrementAndDecrement()
{
- TestUnsychronizedIncrementDecrement(Program.Main);
+ Assert.IsFalse(
+ IsIncrementDecrementSynchronized(Program.Main));
}
}
}

ADD
src/Chapter20.Tests/Listing20.02.Tests.cs
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using static AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_01.Tests.ProgramTests;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_02.Tests
+{
+ [TestClass]
+ public class ProgramTests
+ {
+
+ [TestMethod]
+ public void UnsynchronizedIncrementAndDecrement()
+ {
+ Assert.IsFalse(
+ IsIncrementDecrementSynchronized(Program.Main));
+ }
+ }
+}

MODIFY
src/Chapter20.Tests/Listing20.03.Tests.cs
src/Chapter20.Tests/Listing20.03.Tests.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using static AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_01.Tests.ProgramTests;
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_03.Tests
{
[TestClass]
public class ProgramTests
{
- public static void TestUnsychronizedIncrementDecrement(Action action)
- {
- string expected = @"Count = 0";
-
- IntelliTect.TestTools.Console.ConsoleAssert.Expect(expected,
- () =>
- {
- action();
- });
- }
[TestMethod]
- public void SyncorhinzedIncrementAndDecrement()
+ public void SynchronizedIncrementAndDecrement()
{
- TestUnsychronizedIncrementDecrement(Program.Main);
+ Assert.IsFalse(
+ IsIncrementDecrementSynchronized(Program.Main));
}
}
}

MODIFY
src/Chapter20.Tests/Listing20.04.Tests.cs
src/Chapter20.Tests/Listing20.04.Tests.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using static AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_01.Tests.ProgramTests;
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_04.Tests
{
- using static Listing20_03.Tests.ProgramTests;
[TestClass]
public class ProgramTests
{
[TestMethod]
- public void Unsynchronized()
+ public void SynchronizedIncrementAndDecrement()
{
- TestUnsychronizedIncrementDecrement(Program.Main);
+ Assert.IsFalse(
+ IsIncrementDecrementSynchronized(Program.Main));
}
}

MODIFY
src/Chapter20.Tests/Listing20.05.Tests.cs
src/Chapter20.Tests/Listing20.05.Tests.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using static AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_01.Tests.ProgramTests;
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter20.Listing20_05.Tests
{
- using static Listing20_03.Tests.ProgramTests;
[TestClass]
public class ProgramTests
{
[TestMethod]
- public void Unsynchronized()
+ public void SynchronizedIncrementAndDecrement()
{
- TestUnsychronizedIncrementDecrement(()=>Program.Main().Wait());
+ Assert.IsTrue(
+ IsIncrementDecrementSynchronized(
+ (args) =>
+ {
+ Program.Main(args).Wait();
+ }));
}
}

MODIFY
src/Chapter20/Listing20.03.SynchronizingWithMonitor.cs
src/Chapter20/Listing20.03.SynchronizingWithMonitor.cs
public class Program
{
readonly static object _Sync = new object();
- const int _Total = int.MaxValue;
+ static int _Total = int.MaxValue;
static long _Count = 0;
- public static void Main()
+ public static void Main(string[] args)
{
+ if (args?.Length > 0) { int.TryParse(args[0], out _Total); }
+ Console.WriteLine($"Increment and decrementing {_Total} times...");
+
// Use Task.Factory.StartNew for .NET 4.0
Task task = Task.Run(() => Decrement());

MODIFY
src/Chapter20/Listing20.04.SynchronizingWithLockKeyword.cs
src/Chapter20/Listing20.04.SynchronizingWithLockKeyword.cs
public class Program
{
readonly static object _Sync = new object();
- const int _Total = int.MaxValue;
+ static int _Total = int.MaxValue;
static long _Count = 0;
- public static void Main()
+ public static void Main(string[] args)
{
+ if (args?.Length > 0) { int.TryParse(args[0], out _Total); }
+ Console.WriteLine($"Increment and decrementing {_Total} times...");
+
// Use Task.Factory.StartNew for .NET 4.0
Task task = Task.Run(() => Decrement());

MODIFY
src/Chapter20/Listing20.05.AsyncMain.cs
src/Chapter20/Listing20.05.AsyncMain.cs
public class Program
{
readonly static object _Sync = new object();
- const int _Total = int.MaxValue;
+ static int _Total = int.MaxValue;
static long _Count = 0;
- public static async Task Main()
+ public static async Task Main(string[] args)
{
+ if (args?.Length > 0) { int.TryParse(args[0], out _Total); }
+ Console.WriteLine($"Increment and decrementing {_Total} times...");
+
// Use Task.Factory.StartNew for .NET 4.0
Task task = Task.Run(() => Decrement());

Attempted to switch to us Parralel.For() but failed since Console is static and cannot support multithreaded redirection.