我正试图围绕Windows窗体应用程序的线程模型,并且失败了。我们有一个带有你添加的字符串数组的类/模块,很明显一个添加被其他调用/线程踩到了。
因此我们将一个小测试工具放在一起试图复制它:
Friend Module ErrTest
<ThreadStatic()> Friend ErrLog As String = ""
End Module
Public Class ErrLogTest
Public Sub New(T As Integer)
SyncLock ErrLog
For I = 1 To 10
ErrLog &= "Test " & T & " Count " & I & "; "
Threading.Thread.Sleep(100)
Next
End SyncLock
End Sub
Public Function GetError() As String
Dim Ans As String = ErrLog
Return Ans
End Function
Public Sub SetError()
ErrLog = ""
End Sub
End Class
这是我主要表单中的代码,它是一个按钮和三个标签:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim EL As ErrLogTest.ErrLogTest
EL = New ErrLogTest.ErrLogTest(1)
Windows.Forms.Application.DoEvents()
Label1.Text = EL.GetError
EL.SetError()
EL = New ErrLogTest.ErrLogTest(2)
Windows.Forms.Application.DoEvents()
Label2.Text = EL.GetError
EL.SetError()
EL = New ErrLogTest.ErrLogTest(3)
Windows.Forms.Application.DoEvents()
Label3.Text = EL.GetError
EL.SetError()
End Sub
如果按一次按钮,则会在三个表单标签中显示三个输出。好极了!但是如果你在更新过程中按下按钮,你会得到部分输出,然后用单个字段中两个循环的输出重绘。
我尝试过在各个地方使用ThreadStatic和Synclock的各种组合无济于事。上面的例子在Add中有锁,但是我把它们放进去并从其他方法中取出来试图找到一个模式,没有运气。
这是一个线程问题吗?或者我错过了一些非常明显的东西?
我们无法控制调用DLL的程序,因此我们无法修改它们。无论我们使用什么解决方案都需要在我们的模块中。
答案 0 :(得分:0)
不要在Synclock中使用“String”。
每次分配时都会创建字符串,因此在每次调用例程期间锁定一个新对象。
像这样创建一个全局和静态的虚拟对象......
Public Shared SyncRoot as new object
此外,您需要将访问权限包装到您正在访问它的任何地方。不只是分配给它的一个例程。
Public Class ErrLogTest
Public Shared SyncRoot as new object
Public Sub New(T As Integer)
SyncLock SyncRoot
For I = 1 To 10
ErrLog &= "Test " & T & " Count " & I & "; "
Threading.Thread.Sleep(100)
Next
End SyncLock
End Sub
Public Function GetError() As String
SyncLock SyncRoot
Dim Ans As String = ErrLog
Return Ans
end synclock
End Function
Public Sub SetError()
SyncLock SyncRoot
ErrLog = ""
End Synclock
End Sub
End Class