VB.NET 中的线程安全变量
Posted
技术标签:
【中文标题】VB.NET 中的线程安全变量【英文标题】:Thread safe variable in VB.NET 【发布时间】:2011-04-24 10:20:09 【问题描述】:当多个用户访问同一页面时,这是声明dbreaders的正确方式吗?
public dbReader as system.Data.IDataReader
在班级级别或
Dim dbReader as System.Data.IDataReader
在类内的每个函数中。
在 VB.Net 中使 dbReader 线程安全的最佳做法是什么?
将它们声明为静态会使其线程安全吗?
提前致谢,
【问题讨论】:
“将它们声明为静态会使其线程安全吗?” - 不。相反。 【参考方案1】:如果您希望每个线程修改变量而不会“害怕”另一个线程会在同一行的某处更改它,最好使用ThreadStatic
属性来修饰变量。
ThreadStatic
属性为创建的每个线程创建不同的变量实例,因此您确信不会出现任何竞争条件。
示例 (来自 MSDN)
Imports System
<ThreadStatic> Shared value As Integer
【讨论】:
我认为这会很有帮助。【参考方案2】:我建议您尽可能使用reentrant functions,根据定义,它是线程安全的,而不是使用类字段:
Function GetIds() As IEnumerable(Of Integer)
Dim result = New List(Of Integer)()
Using conn = New SqlConnection("SomeConnectionString")
Using cmd = conn.CreateCommand()
conn.Open()
cmd.CommandText = "SELECT id FROM foo"
Using reader = cmd.ExecuteReader()
While reader.Read()
result.Add(reader.GetInt32(0))
End While
End Using
End Using
End Using
Return result
End Function
【讨论】:
我使用 DAAB 打开和关闭连接。然后调用该数据访问方法,该方法又将结果集返回为 dbreader。从 aspx 页面我将声明一个 dbreader,获取该数据并使用它。例如 If sClose = 1 And iAssnKey > 0 Then dbReader = DAL.GetAssnCtrlPKey(ClientKey, iAssnKey) If Validation.Validate_DataReader(dbReader) Then If dbReader.Read = True Then If DB_Objects.Convert_objToBool(dbReader.Item ("Active")) = False Then sClose = 0 End If End If End If Validation.Close_DataReader(dbReader) End If 你不应该关闭连接。您应该像我的示例中那样简单地处理它们,以便它们正确地返回到连接池。不需要类/静态字段。 所以首先当我调用数据访问方法时,它会打开连接返回数据。一旦我使用了数据,我应该处理 dbreader.Like dbReader.Dispose()。而且我不会在任何地方明确关闭连接。 就像我的例子一样使用Using
。它会照顾一切。您无需显式调用reader.Dispose
。【参考方案3】:
如果您在函数中Dim
ing 变量,则没有其他线程可以访问该变量,使其根据定义是线程安全的。
但是,如果您在类级别声明它,您可能希望使用SyncLock
,如果它当前正被其他线程使用,它将阻止其他线程访问它。
例子:
Public Sub AccessVariable()
SyncLock Me.dbReader
'Work With dbReader
End SyncLock
End Sub
【讨论】:
因此,如果另一个线程也在访问同一个阅读器的同一页面并尝试更新或插入编码为 Synlock 的阅读器。这会导致检索到的数据不一致吗? @sony:如果您每次都使用上面的SyncLock
来处理变量,则不会。 SyncLock
是为了防止两个线程处理同一个变量。第二个线程将休眠直到锁被释放。
好的,这有帮助。你有什么建议,比如我在一个类中有 3 个函数。这些函数中的每一个都调用不同的数据访问方法,并将结果集作为数据读取器。现在我在 aspx 页面中声明一个数据读取器,并说像 dbreader=GetFunction1Data(pkey)。
现在为了打开阅读器线程安全模式,我应该这样说。公共子函数1()
synclock Me.dbreader '使用 dbreader end synclock end sub以上是关于VB.NET 中的线程安全变量的主要内容,如果未能解决你的问题,请参考以下文章