1

这是我的代码:

<ThreadStatic()>
Dim _GlobalConnection As TdConnection

Public Property GlobalConnection As TdConnection
    Get
        If _GlobalConnection Is Nothing Then
            _GlobalConnection = New TdConnection
        End If
        If _GlobalConnection.State <> ConnectionState.Open Then
            OpenConnection(_GlobalConnection)
        End If
        Return _GlobalConnection
    End Get
    Set(ByVal value As TdConnection)
        _GlobalConnection = value
    End Set
End Property

它位于 ASP.NET Web 应用程序的一个模块中,因此所有成员根据定义都是共享/静态的。我的目标本质上是懒惰。我在任何地方都使用连接,因此拥有一个线程静态属性是有意义的,这样它就可以作为每个线程的一个新实例,而不是每次我想使用它时都会使新的连接对象变暗。

这似乎一直有效,直到我决定在两个不同的浏览器中加载相同的页面。当我这样做时,会抛出一个异常,指出连接对象已在使用中。

我在 Microsoft 文章中读到,不能保证实例类型是线程安全的。如果是这种情况,我该怎么做才能确保此属性及其字段是线程安全的?

编辑:令人困惑的是此代码在页面加载事件中起作用:

Dim Tasks As New List(Of Task)

Tasks.Add(Task.Factory.StartNew(Sub() ucEmployee.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucSales.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucServers.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucApps.LoadData()))

Task.WaitAll(Tasks.ToArray())

这些 .LoadData() 方法中的每一个都在一个单独的线程中执行,并且它们都引用了我上面的 GlobalConnection 属性。我最初在没有 ThreadStatic 属性的情况下编写了所有这些内容。遇到错误后,我创建了 GlobalConnection 属性 ThreadStatic,问题就消失了。当它投入生产时,这个网络应用程序将被多人使用。这就是促使我在两个 Web 浏览器中打开同一页面的原因。我认为那将是两个单独的线程,但也许我错了。

4

2 回答 2

2

每个请求应该有一个连接,而不是每个线程一个。

为此,请将其存储在HttpContext.Current.Items而不是 ThreadStatic 字段中。
您还应该在EndRequest处理程序中关闭连接。

于 2011-11-23T14:23:03.667 回答
2

它不起作用,因为它不是static,它需要属性才能static应用ThreadStatic

于 2012-12-05T19:51:43.000 回答