Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.Net。同步访问(互斥)_Asp.net_Multithreading_Nhibernate_Synchronization - Fatal编程技术网

Asp.Net。同步访问(互斥)

Asp.Net。同步访问(互斥),asp.net,multithreading,nhibernate,synchronization,Asp.net,Multithreading,Nhibernate,Synchronization,为了在web环境中同步访问我的NHibernate会话,我尝试使用互斥锁: public class FactoryRepository { private FactoryRepository() { } private static Mutex _sessionMutex = new Mutex(); private static ISessionFactory factory; public static ISessionFactory SessionFact

为了在web环境中同步访问我的NHibernate会话,我尝试使用互斥锁:

public class FactoryRepository
{
    private FactoryRepository() { }
    private static Mutex _sessionMutex = new Mutex();
    private static ISessionFactory factory;
    public static ISessionFactory SessionFactory
    {
        get
        {
            factory = factory ?? new Configuration().Configure().BuildSessionFactory();
            return factory;
        }
    }

    public static ISession Session
    {
        get
        {
            ISession currentSession;
            _sessionMutex.WaitOne();
            if (HttpContext.Current != null)
            {
                HttpContext context = HttpContext.Current;
                currentSession = context.Items[SessionKey] as ISession;
                if (currentSession == null || !currentSession.IsOpen)
                {
                    currentSession = SessionFactory.OpenSession();
                    context.Items[SessionKey] = currentSession;
                }
            }

            _sessionMutex.ReleaseMutex();
            return currentSession;

        }
    }
}
在记录错误时,我得到:

System.Threading.AbandonedMutexException: The wait completed due to an abandoned mutex.
Method: Boolean WaitOne(Int64, Boolean)

Stack Trace:

 at System.Threading.WaitHandle.WaitOne(Int64 timeout, Boolean exitContext)
 at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
 at System.Threading.WaitHandle.WaitOne()

为什么调用ReleaseMutex会出现这种异常

您的问题在这条线上

 _sessionMutex.WaitOne();
WaitOne可以抛出这个,因为其他线程锁定它,退出时没有out

在您的例子中,WaitOne抛出此异常是因为在另一个线程中放弃了相同的互斥

我建议在类中扭曲互斥体,并使用如下代码:

            try
            {
                cLock = _sessionMutex.WaitOne();
                // call your work
            }
            catch (AbandonedMutexException)
            {
                cLock = true;
                // call your work
            }
            catch (Exception x)
            {
                //Error
            }
            finally
            {
               _sessionMutex.ReleaseMutex();
            }
在上面的代码中,如果用户停止/放弃页面,线程丢失/删除页面,则ReleaseMutex可能无法运行。这就是为什么你会得到这个例外

请注意,互斥锁可以按您的方式永久锁定!:最好在等待中添加毫秒限制,和/或处理非锁定情况以返回只读数据。如果互斥不能通过WaitOne,用户可以长时间锁定


也要小心,互斥锁需要关闭并处理!即使这与MSDN中的示例类似,但在MSDN中只是一个简单的示例,您需要确保关闭并处理互斥锁,否则在更新页面时会看到更多问题。例如,如果在您更新页面时互斥锁保持在内存锁定状态,那么您的页面可能会锁定很长时间,直到垃圾收集将其杀死为止(如果他们这样做)。

您的问题就在这一行

 _sessionMutex.WaitOne();
WaitOne可以抛出这个,因为其他线程锁定它,退出时没有out

在您的例子中,WaitOne抛出此异常是因为在另一个线程中放弃了相同的互斥

我建议在类中扭曲互斥体,并使用如下代码:

            try
            {
                cLock = _sessionMutex.WaitOne();
                // call your work
            }
            catch (AbandonedMutexException)
            {
                cLock = true;
                // call your work
            }
            catch (Exception x)
            {
                //Error
            }
            finally
            {
               _sessionMutex.ReleaseMutex();
            }
在上面的代码中,如果用户停止/放弃页面,线程丢失/删除页面,则ReleaseMutex可能无法运行。这就是为什么你会得到这个例外

请注意,互斥锁可以按您的方式永久锁定!:最好在等待中添加毫秒限制,和/或处理非锁定情况以返回只读数据。如果互斥不能通过WaitOne,用户可以长时间锁定


也要小心,互斥锁需要关闭并处理!即使这与MSDN中的示例类似,但在MSDN中只是一个简单的示例,您需要确保关闭并处理互斥锁,否则在更新页面时会看到更多问题。例如,如果在您更新页面时互斥锁保持在内存锁定状态,那么您的页面可能会锁定很长时间,直到垃圾收集将其杀死,如果他们真的这样做了。

除非您使用的是非常旧版本的NHibernate,否则我认为这可能是杀伤力过大。NHibernate已经能够在web环境中为您提供上下文会话管理,我认为它将为您提供更可靠的管理


看看这篇文章的第2.3节:

除非您使用的是非常旧的NHibernate版本,否则我认为这可能是过火了。NHibernate已经能够在web环境中为您提供上下文会话管理,我认为它将为您提供更可靠的管理


看看这篇文章的第2.3节:

Windows O/S长期以来一直存在一个错误,即如果未按正确的相反顺序正确解锁,则将一个互斥锁锁定在另一个互斥锁中可能会同时锁定这两个互斥锁


基本上,竞争条件和锁定可能是由于NHibernate使用互斥锁来锁定资源以及您正在使用的互斥锁

Windows O/S长期以来存在一个缺陷,即如果未按正确的相反顺序正确解锁,则将一个互斥锁锁定在另一个互斥锁中可能会同时锁定这两个互斥锁


基本上,竞争条件和锁定可能是由于NHibernate使用互斥锁来锁定资源以及您正在使用的互斥锁

谢谢。我知道我的errorRelease互斥可能无法运行。不幸的是,我无法获得足够的关于处理互斥的信息。我应该怎么称呼ReleaseMutex\Dispose?@Andrew我已经创建了一个单独的类来处理我的互斥。而且我从不使用匿名互斥,我总是对waitone设置时间限制。在这个类中,如果不再需要互斥对象,我会在释放互斥对象时关闭并处理它。在我看来,只有在应用程序中使用多个池时,才需要使用互斥。如果没有,那么您尝试的代码是线程安全的,或者您可以使用简单的锁定功能。谢谢。我知道我的errorRelease互斥可能无法运行。不幸的是,我无法获得足够的关于处理互斥的信息。我应该怎么称呼ReleaseMutex\Dispose?@Andrew我已经创建了一个单独的类来处理我的互斥。而且我从不使用匿名互斥,我总是对waitone设置时间限制。在这个类中,如果不再需要互斥对象,我会在释放互斥对象时关闭并处理它。在我看来,只有在应用程序中使用多个池时,才需要使用互斥。如果不是,那么您尝试的代码是线程安全的,或者您可以使用简单的锁函数。