asp.net全局synclock对象

时间:2011-02-07 10:59:14

标签: asp.net multithreading synclock

在asp.net中是否有一种方法可以确保某个线程sub不会同时运行两次,无论如何?

我现在的代码是

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函数只是将消息写入表中。

表格中的消息应该一次又一次地出现(进入,退出,退出),但实际上,他们没有。我喜欢进入,退出,进入,退出,退出...

这意味着synclock未完成。那是真的吗?

如果是这样,我们如何在代码块,跨请求和跨会话实现完整的synclock?

编辑:我需要这个锁,因为真正的代码将根据数据库中的邮件类型列表发送电子邮件。发送每个邮件类型后,将其标记,然后继续下一个邮件。我不能在处理过程中,另一个线程应该看到这个邮件是未处理的。

请告知

2 个答案:

答案 0 :(得分:2)

您考虑使用静态变量而不是使用HttpRuntime Cache吗?

正如一条说明(可能有助于解释您为什么需要此功能),如果一次只能运行一次,那么您的网站将不会具有很大的可扩展性。

答案 1 :(得分:1)

在C#中(对不起,不懂VB语法)我用这个:

private static readonly object Padlock = new object();
  • 这是一个领域,而不是一个财产,
  • 它是静态的(在VB中,如果我没有弄错的话,那就是“共享”)所以在整个应用程序中都是一样的
  • 一旦您使用此类,它就会初始化一次,而不是在您明确使用该字段时。

使用您的属性/缓存版本,您可能有两个线程尝试获取锁定对象,每个线程创建一个不同的:

  • 线程1检查缓存并找不到对象
  • 线程1停放
  • 线程2检查缓存,找不到对象
  • 线程2创建对象并对其进行缓存,再次检索它并从属性
  • 返回
  • 线程1恢复
  • 线程1创建一个新对象并对其进行缓存,再次检索它并返回与线程2使用不同的锁定对象
  • 任何其他线程将使用线程1的锁定对象