Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7492553
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T16:27:50+00:00 2026-05-29T16:27:50+00:00

when a C# program holds a named semaphore, it does not seem to be

  • 0

when a C# program holds a named semaphore, it does not seem to be released when the application is terminated early (for example by pressing Ctrl+C or closing the console window). At least not until all instances of the process have terminated.

With a named mutex an AbandonedMutexException is raised in this case but not with a semaphore. How do you prevent one program instance from stalling when another program instance has been terminated early?

class Program
{
    // Same with count > 1
    private static Semaphore mySemaphore = new Semaphore(1, 1, "SemaphoreTest");

    static void Main(string[] args)
    {
        try
        {
            // Blocks forever if the first process was terminated
            // before it had the chance to call Release
            Console.WriteLine("Getting semaphore");
            mySemaphore.WaitOne();  
            Console.WriteLine("Acquired...");
        }
        catch (AbandonedMutexException)
        {
            // Never called!
            Console.WriteLine("Acquired due to AbandonedMutexException...");
        }
        catch (System.Exception ex)
        {
            Console.WriteLine(ex);
        }

        Thread.Sleep(20 * 1000);
        mySemaphore.Release();
        Console.WriteLine("Done");
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T16:27:51+00:00Added an answer on May 29, 2026 at 4:27 pm

    In general, you can’t guarantee that a thread releases a semaphore when the thread exits. You can write try/finally blocks and critical finalizers, but those won’t always work if the program terminates abnormally. And, unlike mutexes, other threads won’t be notified if a thread exits while it still holds the semaphore.

    The reason is that the Windows semaphore object, on which the .NET Semaphore object is based, doesn’t keep track of which threads have acquired it, and therefore can’t throw an exception similar to the AbandonedMutexException.

    That said, you can be notified when the user closes the window. You need to set a control handler to listen to particular events. You call the Windows API function SetConsoleCtrlHandler, passing it a callback function (delegate) that handles the events you’re interested in. It’s been a while since I did this, but in general.

    Create a managed prototype for the SetConsoleCtrlHandler function, and the callback:

    /// <summary>
    /// Control signals received by the console control handler.
    /// </summary>
    public enum ConsoleControlEventType: int
    {
        /// <summary>
        /// A CTRL+C signal was received, either from keyboard input or from a
        /// signal generated by the GenerateConsoleCtrlEvent function.
        /// </summary>
        CtrlC = 0,
        /// <summary>
        /// A CTRL+BREAK signal was received, either from keyboard input or from
        /// a signal generated by GenerateConsoleCtrlEvent.
        /// </summary>
        CtrlBreak = 1,
        /// <summary>
        /// A signal that the system sends to all processes attached to a console
        /// when the user closes the console (either by clicking Close on the console
        /// window's window menu, or by clicking the End Task button command from
        /// Task Manager).
        /// </summary>
        CtrlClose = 2,
        // 3 and 4 are reserved, per WinCon.h
        /// <summary>
        /// A signal that the system sends to all console processes when a user is logging off. 
        /// </summary>
        CtrlLogoff = 5,
        /// <summary>
        /// A signal that the system sends to all console processes when the system is shutting down. 
        /// </summary>
        CtrlShutdown = 6
    }
    
    /// <summary>
    /// Control event handler delegate.
    /// </summary>
    /// <param name="CtrlType">Control event type.</param>
    /// <returns>Return true to cancel the control event.  A return value of false
    /// will terminate the application and send the event to the next control
    /// handler.</returns>
    public delegate bool ConsoleCtrlHandlerDelegate(ConsoleControlEventType CtrlType);
    
    [DllImport("kernel32.dll", SetLastError=true)]
    public static extern bool SetConsoleCtrlHandler(
    ConsoleCtrlHandlerDelegate HandlerRoutine,
    bool Add);
    

    Now, create your handler method:

    private static bool ConsoleCtrlHandler(ConsoleControlEventType CtrlType)
    {
        switch (CtrlType)
        {
            case CtrlClose:
                // handle it here
                break;
            case CtrlBreak:
                // handle it here
                break;
        }
        // returning false ends up calling the next handler
        // returning true will prevent further handlers from being called.
        return false;
    }
    

    And, finally, during initialization you want to set the control handler:

    SetConsoleCtrlHandler(ConsoleControlHandler);
    

    Your control handler will now be called when the user closes the window. That will allow you to release the semaphore or do other cleanup.

    You might be interested in my ConsoleDotNet package. I wrote three articles about this stuff, the last two of which are still available at DevSource. I don’t know what happened to the first one.

    • Console Input in .NET
    • Working with Console Screen Buffers in .NET
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I work on a program in Delphi that holds a lot of data, and
I created a program that more or less holds an array of strings as
In my iPad program I have an array which holds images. How can I
I read that argv[0] holds the program name i.e. the name by which we
i m trying to build an invoice program that holds data in an Access
I have a SQL Server that holds a lot of data. An application, running
I wrote a little program which prints help information if argument is not passed.
I'm writing a program that uses SetWindowRgn to make transparent holes in a window
I have the following program to open lot's of sockets, and hold them open
I am designing an XML schema to hold the output of my program. However,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.