Why ApplicationException is thrown?

允我心安 提交于 2019-12-23 03:06:58

问题


I am just experimenting on Mutex and wrote the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Mutex_WaitOnewithTimeouts
{
    class Program
    {
        private static Mutex mut = new Mutex();
        private static int numOfThreads = 5;
        private static int numOfIterations = 3;
        private static Random rand = new Random();

        static void Main(string[] args)
        {
            Thread[] threads = new Thread[5];
            for (int num = 0; num < numOfThreads; num++)
            {
                threads[num] = new Thread(new ThreadStart(MyThreadProc));
                threads[num].Name = String.Format("Thread{0}", num);
                threads[num].Start();
            }
            Console.Read();
        }

        private static void MyThreadProc()
        {
            for (int iteration = 0; iteration < numOfIterations; iteration++)
            {
                UseResource();
            }
        }

        private static void UseResource()
        {
            Console.WriteLine("{0} accessing ", Thread.CurrentThread.Name);
            int time = (int)(rand.NextDouble() * 100);
            try
            {
                if (mut.WaitOne(time))
                {
                    Console.WriteLine("Yippie got mutex for {0}", Thread.CurrentThread.Name);
                    Thread.Sleep((int)rand.NextDouble() * 5000);
                }
                else
                {
                    Console.WriteLine("Nopee.... Timeout occured for {0}", Thread.CurrentThread.Name);
                }
            }
            catch (AbandonedMutexException ex)
            {
                Console.WriteLine(" Exception is caught");
            }
            finally 
            {
                Console.WriteLine("Releasing mutex for {0}", Thread.CurrentThread.Name);
               mut.ReleaseMutex();

            }

        }
    }
}

But I am getting ApplicationException sometimes.. Can someone please help me if there is anything wrong with my code and also please explain when will this exception trigger.

Object synchronization method was called from an unsynchronized block of code. I am getting this in the finally block when trying to release the mutex.


回答1:


You are releasing the mutex even if your WaitOne failed. Move the ReleaseMutex call inside the if statement where you know you have the mutex obtained.




回答2:


@John's answer is correct but for posterity, I think a better pattern would be to set a boolean to be true in the if and then still do the release in the finally block but this time only do it if the boolean is true. The problem is that if any of the if clause throws then the mutex will not be released. I assume you will be adding more to the if clause than just a write and a sleep.

You always want to use a try { ... } finally pattern if you can, but just protect against the waitOne() call returning false. Something like the following:

bool release = false;
try {
    if (mut.waitOne(time)) {
        release = true;
        ...
    } else {
        ...
    }
} catch (AbandonedMutexException ex) {
    ...
} finally {
    ...
    if (release) {
        mut.ReleaseMutex();
    }
}


来源:https://stackoverflow.com/questions/10402464/why-applicationexception-is-thrown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!