﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Eliad commented on The mysterious life of mutexes</title><description>I got the same behaviour for Environment.FailFast and Process.Kill, i.e. AbandonedMutexException is thrown...
  
  
I did a little refactoring to the given samples, and guess what , only Environment.Exit executes cleanly
  
  
using System;
  
using System.Collections.Generic;
  
using System.Text;
  
using System.Diagnostics;
  
using System.Threading;
  
using System.Security;
  
using System.Security.Permissions;
  
  
namespace ConsoleApplication5
  
{
  
    class Program
  
    {
  
        static void Main(string[] args)
  
        {
  
            if (args.Length == 0) return;
  
  
            switch (args[0].ToLower())
  
            {
  
                case "kill":
  
                    Kill(args);
  
                    break;
  
                case "exit":
  
                    Exit(args);
  
                    break;
  
                case "failfast":
  
                    FailFast(args);
  
                    break;
  
                default:
  
                    break;
  
            }
  
        }
  
  
        static void Kill(string[] args)
  
        {
  
            if (args.Length != 1)
  
            {
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("Got mutex");
  
                Thread.Sleep(1000000);
  
            }
  
            else
  
            {
  
                Process p = Process.Start(typeof(Program).Assembly.Location, "kill b");
  
                Thread.Sleep(2000);
  
                p.Kill();
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("got it second");
  
            }
  
        }
  
  
        static void Exit(string[] args)
  
        {
  
            if (args.Length != 1)
  
            {
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("Got mutex");
  
                Thread.Sleep(1000);
  
                Console.WriteLine("Bye, fast");
  
                Environment.Exit(45);
  
            }
  
            else
  
            {
  
                Process p = Process.Start(typeof(Program).Assembly.Location, "exit a");
  
                Thread.Sleep(2000);
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("got it second");
  
            }
  
        }
  
        static void FailFast(string[] args)
  
        {
  
            if (args.Length != 1)
  
            {
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("Got mutex");
  
                Thread.Sleep(1000);
  
                Console.WriteLine("Bye, fast");
  
                Environment.FailFast("blah");
  
            }
  
            else
  
            {
  
                Process p = Process.Start(typeof(Program).Assembly.Location, "failfast a");
  
                Thread.Sleep(2000);
  
                Mutex m = new Mutex(true, "foo");
  
                m.WaitOne();
  
                Console.WriteLine("got it second");
  
            }
  
        }
  
  
    }
  
}
  
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment8</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment8</guid><pubDate>Tue, 04 Mar 2008 10:40:29 GMT</pubDate></item><item><title>Jon Skeet commented on The mysterious life of mutexes</title><description>@Jan: Wow. Weird. What kind of exceptions were you getting? Nice to hear about that though - I'll *attempt* to remember it for the next time this comes up on the newsgroups!
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment7</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment7</guid><pubDate>Fri, 29 Feb 2008 09:17:25 GMT</pubDate></item><item><title>Jan Van Ryswyck commented on The mysterious life of mutexes</title><description>@ Jon Skeet:
  
  
The GC.KeepAlive has some weird side effects when using in Console apps (instead of Windows Forms apps). I used it for a Console app for keeping the Mutex around. I got some weird exceptions from time to time when the app was closing down. It needed some WinDbg debugging to figure it out that the Mutex was causing this behavior (only on production machines). A Using statement around the Mutex solved the issue.
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment6</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment6</guid><pubDate>Thu, 28 Feb 2008 20:31:12 GMT</pubDate></item><item><title>Ayende Rahien commented on The mysterious life of mutexes</title><description>No problem with that.
  
The issue that I have is that it doesn't throw abandon mutex exception
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment5</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment5</guid><pubDate>Thu, 28 Feb 2008 18:38:24 GMT</pubDate></item><item><title>Ron Grabowski commented on The mysterious life of mutexes</title><description>The "Threading in C#" book (http://www.albahari.com/threading/part2.html) says:
  
  
"
  
A good feature of Mutex is that if the application terminates without ReleaseMutex first being called, the CLR will release the Mutex automatically.
  
"
  
  
In case anyone is curious, I'm trying to coordinate resource cleanup between an AppDomain that is being terminated and a new AppDomain that is being bought in to replace it. Specifically when ASP.Net detects that the web.config has changed and brings up a new AppDomain to replace the old AppDomain...if the old AppDomain is taking too long to services the old requests and IIS terminates the process while the old AppDomain has the Mutext will the Mutext be properly released so the new AppDomain can aquire it?
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment4</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment4</guid><pubDate>Thu, 28 Feb 2008 18:35:28 GMT</pubDate></item><item><title>Jon Skeet commented on The mysterious life of mutexes</title><description>I should have said the potential workarounds to avoid the finalizer:
  
  
1) Use a "using" statement with the mutex, so the lifetime is clear
  
2) Use GC.KeepAlive
  
3) Use a static variable
  
  
Personally I'm a fan of approach 1, not that I use Mutex much at all in practice.
  
  
I don't know what effect that would have in your scenarios though - I've no idea whether finally blocks get executed when a process is being killed.
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment3</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment3</guid><pubDate>Thu, 28 Feb 2008 16:29:30 GMT</pubDate></item><item><title>Ayende Rahien commented on The mysterious life of mutexes</title><description>Haven't check, so that might be.
  
I don't think that this is the right behavior, though
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment2</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment2</guid><pubDate>Thu, 28 Feb 2008 16:24:47 GMT</pubDate></item><item><title>Jon Skeet commented on The mysterious life of mutexes</title><description>I can't say I've looked closely enough for sure, but is it possible that you're running into the issue where the Mutex finalizer releases the mutex for you? That trips up a lot of people, very often. I'm too sleepy to check for sure though :)
</description><link>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment1</link><guid>http://ayende.com/3169/the-mysterious-life-of-mutexes#comment1</guid><pubDate>Thu, 28 Feb 2008 16:22:11 GMT</pubDate></item></channel></rss>