我只是试验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();
}
}
}
}
但我有时会收到ApplicationException ..如果我的代码有任何问题,有人可以帮助我吗?请解释这个异常何时触发。
从非同步代码块调用对象同步方法。在尝试释放互斥锁时,我在finally块中得到了这个。
答案 0 :(得分:7)
即使您的WaitOne失败,您也会释放互斥锁。在您知道已获得互斥锁的if语句中移动ReleaseMutex调用。
答案 1 :(得分:0)
@ John的回答是正确的但是对于后人来说,我认为更好的模式是在if
中将布尔值设置为true,然后仍然在release
中执行finally
阻止,但这次只有在布尔值为真时才这样做。问题是,如果任何if
子句抛出,则互斥锁将不会被释放。我假设您将在if
子句中添加更多内容,而不仅仅是写入和休眠。
如果可以,您总是希望使用try { ... } finally
模式,但只是防止waitOne()
调用返回false。如下所示:
bool release = false;
try {
if (mut.waitOne(time)) {
release = true;
...
} else {
...
}
} catch (AbandonedMutexException ex) {
...
} finally {
...
if (release) {
mut.ReleaseMutex();
}
}