Could not write to output file 'c:\xxxx\obj\x86\Debug\yyyy.exe' -- 'The process cannot access the file because it is being used by another process

While compiling in Visual Studio 2012, I was continually getting the following error after every attempt to compile:

Could not write to output file 'c:\xxxx\obj\x86\Debug\yyyy.exe' -- 'The process cannot access the file because it is being used by another process.

For a brief moment of time this file was locked and inaccessible to the IDE. Naturally, I first checked that the Indexing Service or an antivirus app wasn't locking the file. I disabled both and yet the error still occurred after every compile attempt. Closing Visual Studio and rebooting did absolutely nothing.

In fact, I couldn't find any kind of lock on the file and could easily delete it. Subsequently, compiling would succeed, but any time I compiled again it would just lock up once more. Every post I read was indicating that some external process wasn't giving up control of this file, but my gut was telling me the lock was as a result of the compilation itself.

Using Windows Sysinternals Process Monitor I was able to record all access performed on this file.

First MSBuild.exe took a crack at this file, operating on it repeatedly. No issue there.

Sharing violation

Then Csc.exe began using it, initially with success, then later the error "FILE LOCKED WITH ONLY READERS" occurred, ultimately ending with the error "SHARING VIOLATION".

Why was the compiler locking access to the compiled .exe?

When I checked the list of references for each project in the solution, I discovered one of my projects (the one leading to the yyyy.exe that was failing to compile) had a reference to itself! Not sure how a reference to the very same project was added... maybe as a result of some refactoring while using ReSharper?

So if you come across an error about an access violation during compile and it doesn't actually appear to be due to another application (such as an antivirus) grabbing the file before compilation is complete, double-check that your project isn't accidentally referencing itself.

Optional Parameters in C# 4.0

As a C# developer who has done a fair amount of coding in VB.NET too, I've wanted to use optional parameters for some of my overloaded methods long before the capability existed.  Fortunately, optional parameters finally do exist in C# .NET 4.0.

Prior to .NET 4, something like the following needed to be done to effectively allow optional parameters by essentially overloading the same method name multiple times, with a different number of parameters in each signature:

class OptionalParametersTest
{
	public void SomeMethod(string a)
	{
		SomeMethod(a, "default value", "default value");
	}

	public void SomeMethod(string a, string b)
	{
		SomeMethod(a, b, "default value");
	}

	public void SomeMethod(string a, string b, string c)
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

Here's a sample invoking each of these three overloaded methods:

var optionalParametersTest = new OptionalParametersTest();

optionalParametersTest.SomeMethod("1");
optionalParametersTest.SomeMethod("1", "2");
optionalParametersTest.SomeMethod("1", "2", "3");

This will output:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

Here's the same class in the first listing, OptionalParametersTest, but rewritten using optional parameters:

class OptionalParametersTest
{
	public void SomeMethod(string a, string b = "default value", string c = "default value")
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

The output is exactly the same:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

The notation, adding " = default value" after the name of the parameter, is familiar to VB.NET developers too.  And, just like in VB.NET, optional parameters must be defined last; you can't make the first parameter optional if the next one isn't.

But what if you want the second parameter (optional) to remain optional but define the third (also optional) parameter?  How can you get the following result?

a: 1, b: default value, c: 3

The trick is to omit the second parameter and define the third with a colon:

optionalParametersTest.SomeMethod("1", c : "3");

In the above line, we didn't bother specifying the parameter named "b" and instead just indicated that we wanted to define parameter "c".  This instructed the method to use the default value of "b" while still allowing the "c" parameter to be passed in.

Man, there are so many times I wished I could have done this before C# 4.0 hit the scene.

Interprocess Communication With Memory-Mapped Files, Part 3

I wasn't intending to write a third piece on this, but after spending more time with the prototype from the previous post, I realized that we've got a little more redundant code than I typically like to see.  While it's still fresh, I'd like to take the time to clean up the code, making the whole thing more reusable and much easier to extend later if needed.

To recap one last time, we had written two separate applications:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a “shutdown” message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different “unique name” and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a “shutdown” message instructing the ConsoleAppListener to shutdown gracefully when it’s finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different “unique name”.
In the previous post, both ConsoleAppListener and ConsoleAppController reused two crucial functions, which I've wrapped into reusable methods, BroadcastMessage and GetMessage:
private void BroadcastMessage(int message)
{
	_memoryMappedFile = MemoryMappedFile.CreateOrOpen(_memoryMappedFileName, MessageByteSize);

	using (var accessor = _memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
	{
		accessor.Write(0, message);
	}
}

private int GetMessage()
{
	int messageReceived;

	using (var stream = _memoryMappedFile.CreateViewStream())
	{
		var reader = new BinaryReader(stream);
		messageReceived = reader.ReadInt32();
	}

	Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));

	return messageReceived;
}

In addition, I found it was best to encapsulate this communication code into a single class that's common to both classes.  The recurring theme is to make each class do just one thing, and do it well.  For this reason I've created a new project, called "Shared", and wrapped all of the communication logic into one class called InterprocessCommunicator.  This class is referenced by both projects and contains both the BroadcastMessage() and GetMessage() methods.

I've also refactored the other two classes to offload their communication work to the new InterprocessCommunicator, resulting in less redundant and cleaner code.
Project ConsoleAppController\Program.cs:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using Shared;

namespace ConsoleAppController
{
    /// <summary>
    /// Responsible for launching a ConsoleAppListener process with a specific instance name and monitor it,
    /// if one isn't already running. If a ConsoleAppListener is already running, it will begin monitoring.
    /// If the ConsoleAppListener shuts down, this will restart it.
    /// If the user presses any key, the ConsoleAppListener is instructed to shut down gracefully.
    /// </summary>
    class Program
    {
        private const string ClientAppInstanceName = "SampleApp";
        private const string ClientProcessFileName = @"C:\Code\Personal\InterprocessCommunication\ConsoleAppListener\bin\Debug\ConsoleAppListener.exe";

        private static bool _isClientProcessRunning;
        private static bool _isShuttingDown;

        private static readonly InterprocessCommunicator InterprocessCommunicator = new InterprocessCommunicator(ClientAppInstanceName);

        static void Main(string[] args)
        {
            // Determine whether the client process is already running:
            _isClientProcessRunning = InterprocessCommunicator.LocateClient();
            if (_isClientProcessRunning)
            {
                InterprocessCommunicator.ProcessExited += ProcessExited;
                Console.WriteLine("Process already running");
            }
            else
            {
                // Launch the process:
                LaunchProcess();
                Console.WriteLine("Process launched");
            }

            Console.WriteLine("Hit any key to send shutdown message (at any time)");
            Console.ReadKey();

            WantProcessToShutDown();
            Console.WriteLine("Sent message to shut down");

            _isShuttingDown = true;
            Console.WriteLine("Hit Enter to close");
            Console.ReadLine();
        }

        private static void LaunchProcess()
        {
            var process = new Process();

            // Create process to launch the desired application:
            var processProperties = new ProcessStartInfo
                                        {
                                            UseShellExecute = true,
                                            WorkingDirectory = Directory.GetParent(ClientProcessFileName).FullName,
                                            FileName = ClientProcessFileName,
                                            Arguments = ClientAppInstanceName,  // Pass in the application's unique name
                                            RedirectStandardOutput = false
                                        };

            Console.WriteLine(String.Format("Launching executable: {0} {1} ", processProperties.FileName,
                                      processProperties.Arguments));

            process.StartInfo = processProperties;
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;
            process.Start();
            _isClientProcessRunning = true;
        }

        private static void ProcessExited(object sender, EventArgs e)
        {
            Console.WriteLine("Process exited");
            _isClientProcessRunning = false;

            // Start up the process again:
            if (!_isShuttingDown)
            {
                LaunchProcess();
            }
        }

        private static void WantProcessToShutDown()
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            InterprocessCommunicator.BroadcastShutdownMessage();
        }
    }
}

Project ConsoleAppListener\Program.cs:

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Threading;
using Shared;

namespace ConsoleAppListener
{
    /// <summary>
    /// Responsible for performing a unit of work ("processing") at a time,
    /// checking for a message to shutdown between processing.
    /// </summary>
    class Program
    {
        private static string _instanceName;
        private static InterprocessCommunicator _interprocessCommunicator;

        static void Main(string[] args)
        {
            // Get the unique name of this application from the first commandline argument:
            _instanceName = args.Length > 0 ? args[0] : string.Empty;

            if (string.IsNullOrEmpty(_instanceName))
            {
                Console.WriteLine("Error: Expected a unique name for the application from the command line.");
                Console.Read();
                return;
            }

            _interprocessCommunicator = new InterprocessCommunicator(_instanceName);
            _interprocessCommunicator.BroadcastProcessId();

            while (!ShouldClose())
            {
                Console.WriteLine("Close message not received, beginning to process");

                // Perform a unit of work:
                PerformProcessing();

                Console.WriteLine("Processing finished");
            }

            Console.WriteLine("Close message received. Hit Enter to close");
            Console.Read();
        }

        private static bool ShouldClose()
        {
            return _interprocessCommunicator.CheckForShutdownMessage();
        }

        static void PerformProcessing()
        {
            Console.WriteLine("Performing processing");

            // Begin processing a unit of work

            // In this case, just sleep. In real world, processing code goes here:
            Thread.Sleep(6000);  // 6 sec
        }
    }
}
Project Shared\InterprocessCommunicator.vb:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace Shared
{
    public class InterprocessCommunicator
    {
        private const int MessageByteSize = 4;  // Number of bytes needed to store an int32
        private const int ShutdownMessage = -1;

        private MemoryMappedFile _memoryMappedFile;
        private readonly string _memoryMappedFileName;

        public EventHandler ProcessExited;

        public InterprocessCommunicator(string memoryMappedFileName)
        {
            _memoryMappedFileName = memoryMappedFileName;
        }

        #region Public Methods

        public bool LocateClient()
        {
            try
            {
                _memoryMappedFile = MemoryMappedFile.OpenExisting(_memoryMappedFileName);
            }
            catch (FileNotFoundException)  // Exception-driven logic is never ideal, but no method exists to check for the file first
            {
                return false;  // Client not found
            }

            // Read the process ID from the memory-mapped file:
            var messageReceived = GetMessage();

            // Check if the latest message in the file is a shutdown message
            // sent from a previous instance of this application
            // (which means that the client app is still running but no longer listening-- likely it's shutting down)
            if (messageReceived == ShutdownMessage)
            {
                return false;  // Client not found
            }

            var processId = messageReceived;

            // Get the client process by its ID:
            var process = Process.GetProcessById(processId);
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;

            return true;  // Client found
        }

        public bool CheckForShutdownMessage()
        {
            var message = GetMessage();
            if (message == ShutdownMessage)
            {
                Console.WriteLine("Received shutdown message");
                return true;
            }

            return false;
        }

        public void BroadcastProcessId()
        {
            var processId = Process.GetCurrentProcess().Id;
            BroadcastMessage(processId);
        }

        public void BroadcastShutdownMessage()
        {
            BroadcastMessage(ShutdownMessage);
        }

        #endregion

        #region Private Methods

        private void BroadcastMessage(int message)
        {
            _memoryMappedFile = MemoryMappedFile.CreateOrOpen(_memoryMappedFileName, MessageByteSize);

            using (var accessor = _memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, message);
            }
        }

        private int GetMessage()
        {
            int messageReceived;

            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                messageReceived = reader.ReadInt32();
            }

            Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));

            return messageReceived;
        }

        #endregion
    }
}
Previous articles:
Reference:

Interprocess Communication With Memory-Mapped Files, Part 2

In the previous post, I provided a glimpse into how to use a memory-mapped file to establish a primitive interprocess communication system, responsible for passing along the process ID from one process, and a "shutdown gracefully" message from another.

To recap, we have two separate applications:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a “shutdown” message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different “unique name” and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a “shutdown” message instructing the ConsoleAppListener to shutdown gracefully when it’s finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different “unique name”.
It can be difficult to explain in words what code can sometimes help clear up, so below I am posting the Program.cs files for each of the two console applications.  Note that the path to the .exe of the Listener app is hard-coded as a constant in the Controller app.
ConsoleAppListener's Program.cs:

 

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

namespace ConsoleAppListener
{
    /// <summary>
    /// Responsible for performing a unit of work ("processing") at a time,
    /// checking for a message to shutdown between processing.
    /// </summary>
    class Program
    {
        private const int FileSize = 4;  // Maximum number of bytes needed to hold an int32
        private const int CloseMessage = -1;

        private static string _instanceName;
        private static MemoryMappedFile _memoryMappedFile;

        static void Main(string[] args)
        {
            // Get the unique name of this application from the first commandline argument:
            _instanceName = args.Length > 0 ? args[0] : string.Empty;

            if (string.IsNullOrEmpty(_instanceName))
            {
                Console.WriteLine("Error: Expected a unique name for the application from the command line.");
                Console.Read();
                return;
            }

            _memoryMappedFile = MemoryMappedFile.CreateOrOpen(_instanceName, FileSize);

            using (var accessor = _memoryMappedFile.CreateViewAccessor(0, FileSize))
            {
                var processId = Process.GetCurrentProcess().Id;
                accessor.Write(0, processId);
            }

            while (!ShouldClose())
            {
                Console.WriteLine("Close message not received, beginning to process");

                // Perform a unit of work:
                PerformProcessing();
            }

            Console.WriteLine("Close message received. Hit Enter to close");
            Console.Read();
        }

        private static bool ShouldClose()
        {
            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                var message = reader.ReadInt32();
                if (message == CloseMessage)
                {
                    Console.WriteLine("Received shutdown message");
                    return true;
                }
            }

            return false;
        }

        static void PerformProcessing()
        {
            Console.WriteLine("Performing processing");

            // Begin processing a unit of work

            // In this case, just sleep. In real world, processing code goes here:
            Thread.Sleep(6000);  // 6 sec
        }
    }
}
ConsoleAppController's Program.cs:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace ConsoleAppController
{
    /// <summary>
    /// Responsible for launching a ConsoleAppListener process with a specific instance name and monitor it,
    /// if one isn't already running. If a ConsoleAppListener is already running, it will begin monitoring.
    /// If the ConsoleAppListener shuts down, this will restart it.
    /// If the user presses any key, the ConsoleAppListener is instructed to shut down gracefully.
    /// </summary>
    class Program
    {
        private const int MessageByteSize = 4;  // Number of bytes needed to store an int32
        private const int CloseMessage = -1;
        private const string ClientAppInstanceName = "SampleApp";
        private const string ClientProcessFileName = @"C:\Code\Personal\InterprocessCommunication\ConsoleAppListener\bin\Debug\ConsoleAppListener.exe";

        private static bool _isClientProcessRunning;
        private static bool _isShuttingDown;

        static void Main(string[] args)
        {
            // Determine whether the client process is already running:
            _isClientProcessRunning = LocateClient(ClientAppInstanceName);
            if (_isClientProcessRunning)
            {
                Console.WriteLine("Process already running");
            }
            else
            {
                // Launch the process:
                LaunchProcess();
                Console.WriteLine("Process launched");
            }

            Console.WriteLine("Hit any key to send shutdown message (at any time)");
            Console.ReadKey();

            WantProcessToShutDown(ClientAppInstanceName);

            _isShuttingDown = true;
            Console.WriteLine("Hit Enter to close");
            Console.ReadLine();
        }

        private static bool LocateClient(string clientAppUniqueName)
        {
            MemoryMappedFile memoryMappedFile;

            try
            {
                memoryMappedFile = MemoryMappedFile.OpenExisting(clientAppUniqueName);
            }
            catch (FileNotFoundException)  // Exception-driven logic is never ideal, but no method exists to check for the file first
            {
                return false;  // Client not found
            }

            int messageReceived;

            // Read the process ID from the memory-mapped file:
            using (memoryMappedFile)
            {
                using (var stream = memoryMappedFile.CreateViewStream())
                {
                    var reader = new BinaryReader(stream);
                    messageReceived = reader.ReadInt32();
                    Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));
                }
            }

            // Check if the latest message in the file is a shutdown message
            // sent from a previous instance of this application
            // (which means that the client app is still running but no longer listening-- likely it's shutting down)
            if (messageReceived == CloseMessage)
            {
                return false;
            }

            var processId = messageReceived;

            // Get the client process by its ID:
            var process = Process.GetProcessById(processId);
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;

            return true;
        }

        private static void LaunchProcess()
        {
            var process = new Process();

            // Create process to launch the desired application:
            var processProperties = new ProcessStartInfo
                                        {
                                            UseShellExecute = true,
                                            WorkingDirectory = Directory.GetParent(ClientProcessFileName).FullName,
                                            FileName = ClientProcessFileName,
                                            Arguments = ClientAppInstanceName,  // Pass in the application's unique name
                                            RedirectStandardOutput = false
                                        };

            Console.WriteLine(String.Format("Launching executable: {0} {1} ", processProperties.FileName,
                                      processProperties.Arguments));

            process.StartInfo = processProperties;
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;
            process.Start();
            _isClientProcessRunning = true;
        }

        private static void ProcessExited(object sender, EventArgs e)
        {
            Console.WriteLine("Process exited");
            _isClientProcessRunning = false;

            // Start up the process again:
            if (!_isShuttingDown)
            {
                LaunchProcess();
            }
        }

        private static void WantProcessToShutDown(string destinationAppName)
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            var memoryMappedFile = MemoryMappedFile.OpenExisting(destinationAppName);

            using (var accessor = memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, CloseMessage);
            }

            Console.WriteLine("Sent message to shut down");
        }
    }
}

Ideally, this has provided you with the framework to create a basic method for allowing two processes to talk; the controller can notify the listener when it's time to shut down gracefully, and the listener can broadcast its process ID in case the controller shut down unexpectedly.

Note: Part 3 was written to refactor the above code in a more efficient and encapsulated format.  I'd highly recommend checking that out too.

Part 1
Part 3

Interprocess Communication With Memory-Mapped Files, Part 1

Memory-mapped files are great concept that have been buried in various versions of Windows for years.  Finally they've been exposed and incorporated into .NET 4.0 and are available in Visual Studio 2010.

A memory-mapped file is essentially just a file, given a unique name-- no extension necessary-- that exists only in memory.  It can be used to cache a large file into memory for faster access and manipulation.  In addition, since they're accessible from the system level, these files can be used to allow multiple processes to communicate (called "interprocess communication").  It's this method of communication that I'd like to try to implement here.

Suppose we have two separate processes, one to perform work, and the other that's simply responsible for starting the first-- like a Windows Service.  In this situation, we're assuming that the Windows Service can't simply perform the work in a child thread, but relies on that other process to do it.

I've created two C# projects, with one intended perform "processing" and the other to launch and communicate with the first:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a "shutdown" message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different "unique name" and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a "shutdown" message instructing the ConsoleAppListener to shutdown gracefully when it's finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different "unique name".
Since a memory-mapped file has a unique name and persists only while a process is using it, it is a strong candidate for meeting these requirements.  The first process to start, expected to be the ConsoleAppController, is responsible for creating the memory-mapped file.  The second process, the ConsoleAppListener, will look for a memory-mapped file with the same unique name it was provided in its command-line arguments.
Here's a rough order of execution, although many of these things can happen in parallel:
  1. ConsoleAppController starts, checks if a memory-mapped file exists with the name "SampleApp"
  2. ConsoleAppController reads the memory-mapped file, checks if a process ID has already been recorded. If so, this means ConsoleAppListener is already running and will now be monitored.  Otherwise launches a new ConsoleAppListener process with the "SampleApp" passed as a command-line argument
  3. ConsoleAppListener starts, creates or opens memory-mapped file with the name "SampleApp"
  4. ConsoleAppListener saves its process ID to the memory-mapped file
  5. ConsoleAppListener performs processing, checking periodically for the shutdown message, "-1"
  6. ConsoleAppController monitors, restarts ConsoleAppListener if it shuts down on its own (e.g. user closes the window)
  7. ConsoleAppController saves a shutdown message, "-1", to the memory-mapped file, instructing ConsoleAppListener to shutdown at an appropriate time (when it's not performing processing)
So in this scenario, the mem0ry-mapped file only needs to be large enough to store an int32, representing either the ConsoleAppListener's process ID or a shutdown message of "-1".  The direction of either message is implied, as the listener only cares about receiving a "-1" and the controller is only interested in a process ID (which is greater than -1).  For that reason, I consider this mechanism more of a passive, broadcast-based communication system, rather than an active, full-duplex sort of client-server arrangement.
Here's some of the code used by the ConsoleAppListener, responsible for listening for a shutdown message:
private static bool ShouldClose()
        {
            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                var message = reader.ReadInt32();
                if (message == CloseMessage)
                {
                    Console.WriteLine("Received shutdown message");
                    return true;
                }
            }

            return false;
        }
Here's part of ConsoleAppController, responsible for locating the memory-mapped file ("destinationAppName" is the name of the memory-mapped file) and sending a shutdown message to the ConsoleAppListener if prompted by the user:
        private static void WantProcessToShutDown(string destinationAppName)
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            var memoryMappedFile = MemoryMappedFile.OpenExisting(destinationAppName);

            using (var accessor = memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, CloseMessage);
            }

            Console.WriteLine("Sent message to shut down");
        }
I hope this preview gives at least some insight into the use of memory-mapped files for primitive interprocess communication.  In tomorrow's post I'll be providing all of the sample code.

How to Catch Multiple Exceptions in C#

Here's a technique for catching more than one exception in a try / catch block.  Typically it's best to only catch the exceptions that your code can handle, so catching the general System.Exception class is discouraged.  But in this case, we're catching the general Exception class only to determine what type of exception it is.  For any exceptions that aren't handled in the if / else if blocks, we'll re-throw the exception for the calling method to handle.

catch (Exception exception)
{
	if (exception is FileNotFoundException)
	{
		Console.WriteLine("Error: File not found");
	}
	else if (exception is ArgumentException || exception is ArgumentNullException || exception is DirectoryNotFoundException)
	{
		Console.WriteLine("Error: Path is invalid or does not exist");
	}
	else
	{
		throw;
	}
}

The entire console application (Program.cs):

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.IO;

namespace MultipleExceptionHandler
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var fileReader = new StreamReader("file.txt"))
                {
                    while (fileReader.Peek() > 0)
                    {
                        Console.WriteLine(fileReader.ReadLine());
                    }
                }
            }
            catch (Exception exception)
            {
                // Check if it's one of three different exceptions:
                if (exception is ArgumentException || exception is ArgumentNullException || exception is DirectoryNotFoundException)
                {
                    Console.WriteLine("Error: Path is invalid or does not exist");
                }
                // Otherwise check if it's another exception:
                else if (exception is FileNotFoundException)
                {
                    // NOTE: This was only an example to demonstrate handling multiple exceptions.
                    //        It's more efficient to use File.Exists(fileName) rather than using an exception
                    //        to drive your logic.
                    Console.WriteLine("Error: File not found");
                }
                // Since we caught the generic System.Exception, this "else" case will
                // throw back up anything that wasn't explicitly caught:
                else
                {
                    throw;
                }
            }
            Console.ReadLine();
        }
    }
}

Mutex Object, Explained

Suppose you have two threads running simultaneously and they are both using a single instance of a particular object (say a global variable, for example) .  How do you guarantee that only one thread uses that object at any given time?

A mutual exclusion ("mutex") is a mechanism that acts as a flag to prevent two threads from performing one or more actions simultaneously.  The entire action that you want to run exclusively is called a critical section or protected section.

Modern programming languages support this natively.  In C#, it's as simple as:

  1. Instantiating a new static Mutex object that's accessible from each thread
  2. Wrapping whatever code you want to be executed in the critical section with that object's WaitOne() and ReleaseMutex() methods in each thread
An overloaded WaitOne() method also accepts a TimeSpan object, useful if the thread should wait only until a period of time has lapsed.  Typically this is employed when there's a risk of deadlock, where two or more threads are waiting for the same mutex to become available simultaneously.  Deadlock is as bad as it sounds, since it can result in an application that has "stalled out" for all intents and purposes.

Here's a sample .NET 4.0 console application that demonstrates the getting and setting of a static global variable between two threads, first without using the Mutex object and then with it.  In the console output, one thread looped 50 times and one ran 200 times (at faster rate).  Each time it retrieved a value from the global variable that it wasn't expecting, the number of "clashes" was incremented.

Obviously this exercise was written to amplify this disadvantage, but you'll note that there is a large amount of unpredictability (clashes) when not using a Mutex object.  However when wrapping the getting and setting the global variable around a critical section, you'll note that no clashes are observed.  In theory we are introducing a small delay when one thread waits until the other leaves its critical section, but provided that you keep your critical section no larger than is absolutely necessary, slightly slower processing is a small price to pay for the benefit of having a predicable result.

Program.cs:

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Threading;

namespace MutexExample
{
    class Program
    {
        private static string _globalVariable = string.Empty;
        private static readonly Mutex GlobalVariableMutex = new Mutex();

        static void Main(string[] args)
        {
            Console.WriteLine("Press Enter to start");
            Console.ReadLine();
            Console.WriteLine("NOT using mutex:");

            var parametersA = new ThreadParameters { Name = "A", SleepTime = 5, UseMutex = false, LoopCount = 50 };
            var parametersB = new ThreadParameters { Name = "B", SleepTime = 3, UseMutex = false, LoopCount = 200 };

            var threadA = new Thread(GetSetGlobalVariable);
            var threadB = new Thread(GetSetGlobalVariable);

            threadA.Start(parametersA);
            threadB.Start(parametersB);

            // Wait until both threads finish:
            threadA.Join();
            threadB.Join();

            Console.WriteLine(Environment.NewLine + "Using mutex:");

            var parametersC = new ThreadParameters { Name = "C", SleepTime = 5, UseMutex = true, LoopCount = 50 };
            var parametersD = new ThreadParameters { Name = "D", SleepTime = 3, UseMutex = true, LoopCount = 200 };

            var threadC = new Thread(GetSetGlobalVariable);
            var threadD = new Thread(GetSetGlobalVariable);

            threadC.Start(parametersC);
            threadD.Start(parametersD);

            // Wait until both threads finish:
            threadC.Join();
            threadD.Join();

            Console.WriteLine(Environment.NewLine + "Press Enter to exit");
            Console.ReadLine();
        }

        private static void GetSetGlobalVariable(Object obj)
        {
            var threadParams = (ThreadParameters) obj;
            var numClashes = 0;  // Count the number of times the global variable wasn't the value it was expected

            for (var i = 0; i < threadParams.LoopCount; i++)
            {
                // Create a new value for the global variable, using a Guid object to ensure a unique value:
                var expectedValue = string.Format("Thread {0} - {1}", threadParams.Name, Guid.NewGuid());

                // If using a Mutex:
                if (threadParams.UseMutex)
                {
                    // Start the critical area / protected section:
                    GlobalVariableMutex.WaitOne();
                }

                // Set the global variable:
                _globalVariable = expectedValue;

                // Insert an artificial wait, simulating additional processing:
                Thread.Sleep(threadParams.SleepTime);

                // Get the global variable:
                var actualValue = _globalVariable;

                // If using a Mutex:
                if (threadParams.UseMutex)
                {
                    // End the critical area / protected section:
                    GlobalVariableMutex.ReleaseMutex();
                }

                // Compare the global variable with the expected value:
                var isClash = expectedValue != actualValue;
                if (isClash)
                {
                    numClashes++;
                }

                //Console.WriteLine(string.Format("Expecting: {0}{3}Actual: {1}{3}Is a clash: {2}{3}", expectedValue, actualValue, isClash, Environment.NewLine));
            }
            Console.WriteLine(String.Format("Number of Thread {0} clashes: {1} out of {2}", threadParams.Name, numClashes, threadParams.LoopCount));
        }
    }
}

Here's a ThreadParameters class that's used for storing some parameters passed to each of the threads.  It's pretty application-specific.

ThreadParameters.cs:

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

namespace MutexExample
{
    class ThreadParameters
    {
        public string Name { get; set; }
        public bool UseMutex { get; set; }
        public int SleepTime { get; set; }
        public int LoopCount { get; set; }
    }
}

References:
http://en.wikipedia.org/wiki/Mutex
http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx