我不确定如何解决这个问题。我有一个这样声明的互斥体:
public class MyNamedLock
{
private Mutex mtx;
private string _strLkName;
public MyNamedLock(string strLockName)
{
_strLkName = strLockName;
//...
mtx = new Mutex(false, _strLkName, out bCreatedNew, mSec);
}
public bool enterLockWithTimeout(int nmsWait = 30 * 1000)
{
_nmsWaitLock = nmsWait;
//Wait
return mtx.WaitOne(nmsWait);
}
public void leaveLock()
{
_nmsWaitLock = 0;
//Release it
mtx.ReleaseMutex();
}
}
然后在 ASP.NET 页面中使用它:
public class MyClass
{
private MyNamedLock gl;
public MyClass()
{
gl = new MyNamedLock("lock name");
}
public void funct()
{
try
{
//Enter lock
if (gl.enterLockWithTimeout())
{
//Do work
}
else
throw new Exception("Failed to enter lock");
}
finally
{
//Leave lock
gl.leaveLock();
}
}
}
这段代码在我的开发环境中没有给我带来任何麻烦,但在生产环境中它有时会抛出这个异常:
Object synchronization method was called from an unsynchronized block of code.
描述有点模糊,但只是跟踪我发现在 mtx.ReleaseMutex();
部分引发了异常。这是什么意思以及如何解决?
最佳答案
您的类(class)和使用方式有一些问题。
- 只有在您之前已锁定(这是您的错误)时才必须释放互斥锁
- 您需要关闭并处置您打开的互斥量
- 另外,最好是在您要使用它之前创建它,而不是在您创建类
MyClass
时创建它。
所以我建议首先将您的类(class)更改为:
public class MyNamedLock
{
private Mutex mtx = null;
private string _strLkName;
// to know if finally we get lock
bool cNeedToBeRelease = false;
public MyNamedLock(string strLockName)
{
_strLkName = strLockName;
//...
mtx = new Mutex(false, _strLkName, out bCreatedNew, mSec);
}
public bool enterLockWithTimeout(int nmsWait = 30 * 1000)
{
_nmsWaitLock = nmsWait;
bool cLock = false;
try
{
cLock = mtx.WaitOne(nmsWait, false);
cNeedToBeRelease = cLock;
}
catch (AbandonedMutexException)
{
// http://stackoverflow.com/questions/654166/wanted-cross-process-synch-that-doesnt-suffer-from-abandonedmutexexception
// http://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception.aspx
cNeedToBeRelease = true;
}
catch (Exception x)
{
// log the error
Debug.Fail("Check the reason of fail:" + x.ToString());
}
return cLock;
}
public void leaveLock()
{
_nmsWaitLock = 0;
if (mtx != null)
{
if (cNeedToBeRelease)
{
try
{
mtx.ReleaseMutex();
cNeedToBeRelease = false;
}
catch (Exception x)
{
Debug.Fail("Check the reason of fail:" + x.ToString());
}
}
mtx.Close();
mtx.Dispose();
mtx = null;
}
}
}
这是你必须调用那个类的方式:
public class MyClass
{
public MyClass()
{
}
public void funct()
{
var gl = new MyNamedLock("lock name");
try
{
//Enter lock
if (gl.enterLockWithTimeout())
{
//Do work
}
else
throw new Exception("Failed to enter lock");
}
finally
{
//Leave lock
gl.leaveLock();
}
}
}
关于c# - ASP.NET C# 代码中的互斥释放问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15422125/