Asp.Net.Доступ к синхронизации (мьютекс) - PullRequest
1 голос
/ 21 июля 2011

для синхронизации доступа к моему сеансу NHibernate в веб-среде. Я пытаюсь использовать Mutex:

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 ();

Ответы [ 3 ]

3 голосов
/ 21 июля 2011

Ваша проблема на этой линии

 _sessionMutex.WaitOne();

WaitOne () может выдать исключения , потому что какой-то другой поток, блокирующий его, завершается без , освобождая его

В вашем случае 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 это только простой пример, вы должны быть уверены, что закрыли и утилизировали свой Mutex, иначе вы увидите больше проблем при обновлении своей страницы. Например, если Mutex остается заблокированным в памяти, пока вы обновляете свою страницу, то ваша страница может блокироваться на долгое время, пока сборщик мусора не убьет ее, если они это сделают.

2 голосов
/ 21 июля 2011

Если вы не используете очень старую версию NHibernate, я думаю, что это, вероятно, излишне.NHibernate уже имеет возможность предоставлять вам контекстное управление сеансами в веб-среде, и я думаю, что он будет управлять более надежно для вас.

Взгляните на раздел 2.3 этого: NHibernate Глава 2 -Архитектура

0 голосов
/ 20 июля 2012

Windows O / S уже давно имеет ошибку, из-за которой блокировка одного мьютекса внутри другого могла блокировать оба, если они не разблокированы должным образом в правильной обратной последовательности.

В основном, состояние гонки и блокировка могут быть вызваны тем, что NHibernate использует мьютекс для блокировки ресурса, а также мьютекс, который вы используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...