不了解表单上的线程模型

时间:2014-01-23 15:48:20

标签: vb.net multithreading

我正试图围绕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的程序,因此我们无法修改它们。无论我们使用什么解决方案都需要在我们的模块中。

1 个答案:

答案 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