Fulproof
Fulproof

Reputation: 4646

Why is AbandonedMutextException thrown and how to avoid it?

The following c# console application (the code copy-pasted from from the article "Using Mutex and WaitOne with Threading in C# .Net") throws before completing

AbandonedMutextException was unhandled.
{"The wait completed due to an abandoned mutex."}{"The wait completed due to an abandoned mutex."}

on the line:

static Mutex mutex = new Mutex(false);  

after passing the last line preventing console input:

Console.ReadLine();

What's wrong and how to correct it?

using System;
using System.Threading;

class Database
{
  static Mutex mutex = new Mutex(false);

  public static void SaveData(string text)
  {
    mutex.WaitOne();
    Console.WriteLine("Database.SaveData - Started");
    Console.WriteLine("Database.SaveData - Working");
    for (int i = 0; i < 100; i++)
    {
      Console.Write(text);
    }
    Console.WriteLine("\nDatabase.SaveData - Ended");
    mutex.Close();
  }
}

class ThreadMutexApp
{
  public static void WorkerThreadMethod1()
  {
    Console.WriteLine("Worker thread #1 - Started");
    Database.SaveData("x");
    Console.WriteLine("Worker thread #1 - Returned from Output");
  }

  public static void WorkerThreadMethod2()
  {
    Console.WriteLine("Worker thread #2 - Started");
    Database.SaveData("o");
    Console.WriteLine("Worker thread #2 - Returned from Output");
  }

  public static void Main()
  {
    ThreadStart worker1 = new ThreadStart(WorkerThreadMethod1);
    ThreadStart worker2 = new ThreadStart(WorkerThreadMethod2);

    Console.WriteLine("Main - Creating worker threads");

    Thread t1 = new Thread(worker1);
    Thread t2 = new Thread(worker2);

    t1.Start();
    t2.Start();

    Console.ReadLine();
  }
}

Upvotes: 0

Views: 702

Answers (1)

Alex
Alex

Reputation: 8116

The Thread whichever enters SaveData() first, closes the static mutex and makes it unusable for the second. mutex.Close(); should be replaced with mutex.ReleaseMutex();

To quote MSDN

Use this method to release all resources held by an instance of WaitHandle. Once this method is called, references to the current instance cause undefined behavior.

Upvotes: 2

Related Questions