asp.net объект глобальной синхронизации - PullRequest
0 голосов
/ 07 февраля 2011

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

код, который у меня сейчас есть,

Public Class CheckClass
ReadOnly Property CheckSessionsLock As Object
    Get
        If HttpRuntime.Cache("CheckSessionsLock") Is Nothing Then HttpRuntime.Cache("CheckSessionsLock") = New Object
        Return HttpRuntime.Cache("CheckSessionsLock")
    End Get
End Property
Sub TryThreads()
    Dim thread = New Thread(AddressOf TryLock)
    thread.Priority = ThreadPriority.Lowest
    thread.Start()
End Sub
Sub TryLock()
    SyncLock CheckSessionsLock
        DoTrace("entered locker")
        For x = 0 To 10000
        Next
        DoTrace("exiting locker")
    End SyncLock
    DoTrace("exited locker")
End Sub
End Class

если я запускаю этот код на каждой странице, то код несколько раз перекрывается. функция DoTrace в коде просто записывает сообщение в таблицу.

сообщения в таблице должны появляться снова и снова по порядку (входить, выходить, выходить), но на самом деле это не так. я как вошел, выходя, вошел, вышел, выход ...

это означает, что синхронизация не завершена. это правда?

если так, как мы можем реализовать полную синхронизацию для блока кода, между запросами и между сеансами?

РЕДАКТИРОВАТЬ: мне нужна эта блокировка, так как реальный код будет отправлять электронные письма, согласно списку типов рассылки в БД. после того, как каждый тип почтового сообщения отправлен, он помечается, а затем продолжается со следующего почтового сообщения. я не могу иметь в середине обработки, другой поток должен видеть эту рассылку как необработанную.

пожалуйста, сообщите

Ответы [ 2 ]

2 голосов
/ 07 февраля 2011

Вместо использования HttpRuntime Cache вы рассматривали возможность использования статической переменной?

Так же, как примечание (может быть полезно объяснить, почему вы хотите эту функцию), ваш веб-сайт не будет очень масштабируемым, если его можно запускать только один раз за один раз.

1 голос
/ 07 февраля 2011

В C # (извините, не знаю синтаксис VB) я использую это:

private static readonly object Padlock = new object();
  • Это поле, а не свойство,
  • Это статично (в VBэто «общий доступ», если я не ошибаюсь), поэтому он одинаков во всем приложении
  • Он инициализируется один раз, как только вы используете этот класс, а не когда вы явно используете поле.

С вашей версией свойства / кэша у вас может быть два потока, пытающихся получить объект блокировки, и каждый из которых создает отдельный:

  • Поток 1 проверяет кэш и не находитобъект
  • поток 1 припаркован
  • поток 2 проверяет кэш, не находит объект
  • поток 2 создает объект и кэширует его, извлекает его снова и возвращает изсвойство
  • Поток 1 возобновляется
  • Поток 1 создает новый объект и кэширует его, извлекает его снова и возвращает другой объект блокировки, чем поток 2 использует
  • Все остальные потоки будутиспользовать объект блокировки потока 1
...