c# - ASP.NET C# 代码中的互斥释放问题

标签 c# asp.net locking mutex

我不确定如何解决这个问题。我有一个这样声明的互斥体:

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)和使用方式有一些问题。

  1. 只有在您之前已锁定(这是您的错误)时才必须释放互斥锁
  2. 您需要关闭并处置您打开的互斥量
  3. 另外,最好是在您要使用它之前创建它,而不是在您创建类 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/

相关文章:

c# - 绑定(bind)到 XAML 中的 Xamarin Picker SelectedItem 而不是重新加载表单

java - 使用 java Lock 和 Condition 对象

go - 如何在 Go 中实现只使用 atomic 的 "i++ and i>=max ? 0: i"

c# - 从路由名称获取相对路径

c# - lock 语句未按预期工作

c# - 在 if 语句中使用 var

c# - 在更新面板中回发后,Bootstrap 工具提示消失

c# - C#中的多重继承问题

asp.net - 如何将 CssClass 应用于 DataGrid HyperLinkColumn 的标题单元格?

javascript - 模态对话框返回值未定义 - 将结果发送到父窗口