简体   繁体   English

为什么抛出ApplicationException?

[英]Why ApplicationException is thrown?

I am just experimenting on Mutex and wrote the following code. 我只是在Mutex上做实验,并编写了以下代码。

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. 但是有时我会收到ApplicationException。如果我的代码有任何问题,有人可以帮助我,也请解释该异常何时触发。

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. 当试图释放互斥锁时,我在finally块中得到了这个。

You are releasing the mutex even if your WaitOne failed. 即使WaitOne失败,您也将释放互斥量。 Move the ReleaseMutex call inside the if statement where you know you have the mutex obtained. 将ReleaseMutex调用移动到if语句内,您知道已获取互斥量。

@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. @John的答案是正确的,但对于后代,我认为一个更好的模式是在if中将布尔值设置为true,然后仍然在finally块中进行release ,但是这次仅在布尔值为true时才这样做。 The problem is that if any of the if clause throws then the mutex will not be released. 问题是,如果任何if子句抛出,则互斥量将不会被释放。 I assume you will be adding more to the if clause than just a write and a sleep. 我假设您将为if子句添加更多内容,而不仅仅是写入和睡眠。

You always want to use a try { ... } finally pattern if you can, but just protect against the waitOne() call returning false. 如果可能的话,您总是想使用try { ... } finally模式,但要防止返回false的waitOne()调用。 Something like the following: 类似于以下内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM