2011-11-23 36 views
1

这里是我的代码:VB.NET 4.0:ThreadStatic不会出现线程安全我TdConnection财产

<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浏览器中打开相同页面的原因。我认为那将是两个不同的主题,但也许我错了。

+0

http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html – SLaks

回答

2

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

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

+0

如果您'在请求中使用多个任务,这无济于事。 – SLaks

+0

所以它看起来像我将不得不声明一个新的连接对象,每次我需要它。 Great = \。好的,谢谢你的链接。它表明线程在ASP.NET应用程序中的工作方式有很大不同。 – oscilatingcretin

1

它不工作,因为它不是static,它需要staticThreadStatic属性应用