VB.NET 4.0:ThreadStatic 对于我的 TdConnection 属性来说似乎不是线程安全的

发布于 2024-12-17 18:41:50 字数 1423 浏览 0 评论 0原文

这是我的代码:

<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,问题就消失了。当它投入生产时,这个网络应用程序将被多人使用。这就是促使我在两个网络浏览器中打开同一页面的原因。我认为那将是两个独立的线程,但也许我错了。

Here's my code:

<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

It's in a module within an ASP.NET web app, so all members are shared/static by definition. My goal here is essentially laziness. I use connections everywhere, so it just made sense to have one property that is thread static so that it serves as a new instance per thread instead of dimming a new connection object every time I want to use it.

This seems to have been working until I decided to load the same page in two separate browsers. When I do this, an exception is thrown that states the connection object is already in use.

I read in a Microsoft article that instance types are not guaranteed to be thread safe. If this is the case, what can I do to ensure that this property and its field are thread safe?

Edit: What has be confused is that this code works within the page load event:

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())

Each one of those .LoadData() methods is executed in a separate thread and all of them reference my GlobalConnection property above. I initially wrote all that without the ThreadStatic attribute. After encountering errors, I made the GlobalConnection property ThreadStatic and the problem went away. When this rolls out into production, this web app will be used by multiple people. This is what prompted me to open the same page in two web browsers. I thought that would have been two separate threads right there, but perhaps I am wrong about that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮光沉寂 2024-12-24 18:41:50

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

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

You should have one connection per request instead of one per thread.

To do that, store it in HttpContext.Current.Items instead of the ThreadStatic field.
You should also close the connection in an EndRequest handler.

迷雾森÷林ヴ 2024-12-24 18:41:50

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

It's not working because it's not static, it needs to be static for the ThreadStatic attribute to apply

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文