这是我的代码:
<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 浏览器中打开同一页面的原因。我认为那将是两个单独的线程,但也许我错了。