vb.net - 不懂表单上的线程模型

标签 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 的程序,因此我们无法修改它们。我们使用的任何解决方案都需要在我们的模块中。

最佳答案

不要在同步时钟中使用“字符串”。

每次分配字符串时都会创建字符串,因此您在每次调用例程期间锁定一个新对象。

创建一个像这样全局和静态的虚拟对象......

Public Shared SyncRoot as new object

此外,您需要在访问 ErrLog 的任何地方包装访问权限。不仅仅是分配给它的一个例程。
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

关于vb.net - 不懂表单上的线程模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21312994/

相关文章:

multithreading - Indy 10 IdTCPClient 使用单独的线程读取数据?

.net - 使用设计器支持将表单作为属性添加到用户控件

.net - 从 .NET 中的另一个线程更改 UI 元素

html - Android:如何从特定网页检索有问题的数据?

java - 需要一个可以支持多个读者的队列

使用 EJB 计时器服务的 Java 多线程

objective-c - 在 Objective-C 中如何标记临界区?

c# - 需要简单的 css 解析指导

c# - 合并两个 EF 查询,无法将 System.Data.Entity.Infrastruct.DbQuery 类型的对象强制转换为 System.Collections.Generic.IEnumerable

python - 如何在Python中处理具有固定线程数的队列中的多个作业