【问题标题】:Textbox doesn't get updated while threading线程处理时文本框未更新
【发布时间】:2013-07-25 19:44:03
【问题描述】:

这是一个名为“Blahing”的模块内的子代码:

    Sub BlahBlah(ByVal Count As Long)
        For i As Long = 0 To Count
            frmBlaher.txtBlah.Appendtext("Blah")
        Next
    End Sub

这是一个名为 frmBlaher 的表单内的按钮单击事件代码:

     Private Sub WriteBlah_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WriteBlah.Click
         Dim Thread As New Threading.Thread(Sub() Blahing.BlahBlah(Val(_
              TxtBlahCount.Text)))

         Thread.Start()
     End Sub

当我在 txtBlahCount 中输入任何数字(例如 10)然后按下 WriteBlah 按钮时,什么也没有发生。我设置了多个断点,我发现“Appendtext”部分出现但不起作用。我检查了 txtBlah 的 Text_Changed 事件,它发生了,但唯一的问题是,我在 txtBlah 中看不到任何文本。我是多线程的新手。我之前读过很多关于这个问题的答案,但没有一个给出一个例子。你能帮忙吗?

【问题讨论】:

  • 为了编辑主线程中的控件,您需要首先研究委托和控件的调用。基本上你不能改变主线程上的任何东西,从不同的线程,而不首先检查 InvokeRequired 并在需要时调用控件。我无法发布任何代码,因为我在手机上。但是谷歌搜索调用控件线程安全,你应该找到你要找的东西:)
  • 对不起,我不太明白,我只能等待任何代码示例
  • 看看BackgroundWorker。围绕它的大量示例比这更有用。 UI 控件在主线程中,如果你想从其他线程更新它们,你必须跳过几个环节。
  • 你很幸运,它什么也没做。从主 UI 线程以外的线程访问控件可能会导致许多不可预知的问题,包括在时空中撕裂一个洞。

标签: multithreading textbox


【解决方案1】:

运行你的代码有点不同,这就是 vb.net 中多线程的结构应该是什么样的(它与 vb.net 没有将命名空间传递给我所理解的模型有关)

这将是您从 MainThread 加载的 startThread 或 w/e 有你

Private Sub DoSomethingSimple()
    Dim DoSomethingSimple_Thread As New Thread(AddressOf DoSimple)
    DoSomethingSimple_Thread.Priority = ThreadPriority.AboveNormal
    DoSomethingSimple_Thread.Start(Me)
End Sub

这将是实际线程本身(新模型/类或同一类)

Private Sub DoSimple(beginform As Form)
    'Do whatever you are doing that has nothing to do with ui

    'For UI calls use the following
    SomethingInvoked(PassibleVariable, beginform)

End Sub

为每次调用主线程编写一个委托和调用方法。

Delegate Sub SomethingInvoked_Delegate(s As Integer, beginform As Form)
Sub SomethingInvoked_Invoke(ByVal s As Integer, beginform As Form)
    If beginform.NameOfControlYouAreUpdating.InvokeRequired Then ' change NameOfControlYouAreUpdating to the Name of Control on the form you wish to update
        Dim d As New SomethingInvoked_Delegate(AddressOf SomethingInvoked_Invoke)
        beginform.Invoke(d, New Object() {s, beginform})
    Else

        'Do something...
        beginform.NameOfControlYouAreUpdating.Condition = Parameter

    End If
End Sub

这是在 vb.net 中测试(非挂起)编写线程的方式

如果您需要进一步帮助将您的代码实施到此模板,请告诉我:P

【讨论】:

  • 首先,SomethingInvoked 不存在,什么是 PassibleVariable。文本框不包含“条件”属性。
【解决方案2】:

这是因为您试图从创建它的线程以外的线程更新控件。您可以使用 Control.Invoke 和 Control.InvokeRequired 方法来解决这个问题。 Control.Invoke 将在创建 Control 的线程上运行传入的委托。

我根本不使用 VB,但您可以尝试以下方式:

Delegate Sub BlahBlahDelegate(ByVal Count As Long)

Sub BlahBlah(ByVal Count As Long)
    If frmBlaher.txtBlah.InvokeRequired Then
        Dim Del As BlahBlahDelegate
        Del = new BlahBlahDelegate(AddressOf BlahBlah)
        frmBlaher.txtBlah.Invoke(Del, New Object() { Count })
    Else
        For i As Long = 0 To Count
            frmBlaher.txtBlah.AppendText("Blah")
        Next
    End If
End Sub

【讨论】:

  • 谢谢,再次......但仍然无法正常工作。它检查 frmBlaher.txtBlah.InvokeRequired 是否为假,然后转到“Else”并开始附加文本。但仍然没有新鲜事
  • 哦,对不起,我看到我的问题应该是:
【解决方案3】:

查看 MSDN 站点,它会为您提供所需的一切。您尤其需要注意 SetText 方法及其对 InvokeRequired 和 Invoke 方法的使用,以及它对委托的使用。

一开始可能会让人望而生畏,但一旦你掌握了窍门,它就会成为第二天性。

这是一个链接http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多