0

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

表格中的消息应该按顺序(进入、退出、退出)一次又一次地出现,但实际上并非如此。我就像进入,退出,进入,退出,退出......

这意味着同步锁未完成。真的吗?

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

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

请指教

4

2 回答 2

2

您是否考虑过使用静态变量而不是使用 HttpRuntime 缓存?

就像注释一样(解释为什么需要此功能可能会有所帮助)如果一次只能运行一次,您的网站将不会具有很强的可扩展性。

于 2011-02-07T12:29:45.693 回答
1

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

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

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

  • 线程 1 检查缓存并没有找到对象
  • 线程 1 已停放
  • 线程 2 检查缓存,没有找到对象
  • 线程 2 创建对象并缓存它,再次检索它并从属性返回
  • 线程 1 恢复
  • 线程 1 创建一个新对象并缓存它,再次检索它并返回与线程 2 使用的不同的锁对象
  • 任何其他线程都将使用线程 1 的锁对象
于 2011-02-07T14:55:51.440 回答