从VB.NET中的另一个类/线程访问TextBox控件时出现问题

时间:2011-04-16 00:55:42

标签: .net vb.net winforms multithreading

我试图从另一个类和线程访问一个richtextbox然后ui和我似乎无法让它工作。我目前有子处理公共类内部的工作,它是一个sharedsub,我将从几个不同的类和线程调用它,但我再也看不到它的工作。代码看起来像这样。

Public Class SharedSubs

Public Shared Sub console(ByVal message As String)
    Dim c As New Form1
    If c.consoleBox.Text.Length > 0 Then
        If c.consoleBox.Text.Substring(c.consoleBox.Text.Length - 3, 3) = "..." Then
            c.consoleBox.AppendText(message)
        ElseIf c.consoleBox.Text.Substring(c.consoleBox.Text.Length - 1, 1) = "." Then
            c.consoleBox.AppendText(ControlChars.NewLine & timeStamp() & message)
        End If
    Else
        c.consoleBox.AppendText(timeStamp() & message)
    End If
End Sub

我将使用SharedSubs.Console("stringstring")调用sub从ui线程调用它工作正常但是当从任何其他线程或类调用它什么也没做时,我已经确认它通过这段代码但它没有显示任何东西在文本框中,它不是由于委托,我认为它会发生异常。

我这样做完全错了吗?一些帮助会很棒,谢谢。

3 个答案:

答案 0 :(得分:2)

您无法从主/ UI线程以外的线程修改Winforms UI组件的显示。要从另一个线程更新,请查看Control.Invoke的文档。它有一个很好的例子。

http://msdn.microsoft.com/en-us/library/zyzhdc6b%28v=VS.100%29.aspx

答案 1 :(得分:1)

理想情况下,使用一个事件,然后你可以将其他东西附加到你的Textupdate ......例如你可能想要显示它并记录它...然后你只需将表单和日志绑定到事件。 / p>

如果你真的想在你的表单上调用该方法,那么你需要在正确的线程上调用它。这可以通过两种方式完成。

在创建Thread的类中,您将对Form / Control的引用传递给构造函数(因此该点位于同一个线程上)。将引用存储在您的班级中。然后创建你的线程。 (不要使用共享以便您引用正确的实例)

Delegate sub ConsoleDelegate(byval message as string)
Public Sub console(ByVal message As String)

在您的主题中,您只需调用表单即可。

mForm.Invoke(new ConsoleDelegate(addressof DoSomething), new object(){message})

OR

从您的主题中,您可以在表单上调用方法,并在表单上的方法内部调用。

private Delegate sub ConsoleDelegate(byval message as string)
Public Sub console(ByVal message As String)
  If me.InvokeRequired then
      me.Invoke(new ConsoleDelegate(addressof DoSomething), new object(){message})
      return
  end if 
  'Do the actual work.
end sub 

答案 2 :(得分:0)

尝试在表单加载时添加此代码:

Me.CheckForIllegalCrossThreadCalls = False

它应该解决问题