我的代码:
<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应用程序,因此根据定义,所有成员都是共享/静态的。我的目标本质上是懒惰。我在任何地方都使用连接,所以有一个属性是线程静态的,这样它就可以作为每个线程的新实例,而不是每次我想使用它时都调光一个新的连接对象。
这似乎一直在工作,直到我决定在两个不同的浏览器加载相同的页面。当我这样做时,会抛出一个异常,指出连接对象已经在使用中。
我在微软的一篇文章中读到实例类型不能保证线程安全。如果是这种情况,我能做些什么来确保这个属性和它的字段是线程安全的?
编辑:令人困惑的是,这段代码在页面加载事件中工作:
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应用程序将被多人使用。这就是促使我在两个浏览器中打开同一个页面的原因。我认为这将是两个独立的线程,但也许我错了。
每个请求应该有一个连接,而不是每个线程一个。
要做到这一点,将其存储在HttpContext.Current.Items
而不是ThreadStatic字段中。
您还应该在EndRequest
处理程序中关闭连接。
它不工作,因为它不是static
,它需要static
ThreadStatic
属性应用