调用主体表格的一部分

时间:2018-07-11 07:05:46

标签: vb.net multithreading

我有一个具有8个线程的应用程序。该应用程序的主要功能是显示4个输出的实时信息,并将信息写入文件。

现在,我对多线程领域了解不多,但是我已经成功创建了4个线程,如果我不将信息记录到富文本框中,则它们工作正常,他们会编写信息放入文件中。

我的问题是:我可以在同一窗体(MainForm)上显示每个输出的实时信息吗? 输出彼此独立工作

enter image description here

以下是我用于将信息登录到richtextbox的代码:

 Public Sub LogInBoxOutput2(ByVal [RichTextBox] As RichTextBox, textColor As Color, ByVal [text] As String, Optional logToFile As Boolean = False)

    Dim textToWrite As String = "[" & Now.ToString("dd:MM:yyyy HH:mm:ss.fff") & "] - " & [text]

    If logNodesValues Then
        Me.InvokeIfRequired(Sub()

                                If textColor = Nothing Then
                                    [RichTextBox].SelectionColor = Color.Black
                                Else
                                    [RichTextBox].SelectionColor = textColor
                                End If


                                [RichTextBox].SelectedText = textToWrite

                                If scrollToBottom Then
                                    [RichTextBox].Select([RichTextBox].Text.Length - 1, 0)
                                    [RichTextBox].ScrollToCaret()
                                End If
                                [RichTextBox].AppendText(vbCrLf)

                                If logToFile Then
                                    writeToFileQueue2.Enqueue(textToWrite & vbCrLf)
                                End If

                            End Sub)
    Else
        writeToFileQueue2.Enqueue(textToWrite & vbCrLf)
    End If
End Sub

  <Extension()>
Public Sub InvokeIfRequired(ByVal Control As Control, ByVal Method As Action)
    If Control.InvokeRequired Then
        Control.Invoke(Method)
    Else
        Method.Invoke()
    End If
End Sub

您有什么想法,我该怎么办?在ASP.NET中是否有类似的内容,您可以仅刷新页面的一帧/一部分(意味着仅调用主窗体的一部分)?

谢谢

1 个答案:

答案 0 :(得分:1)

除了应该调用之外,还应该将所有要输出到UI的消息排入队列,以使UI和处理器得到一些休息。然后使用System.Windows.Forms.TimerInterval为1来尽可能频繁地清空该队列(大约每50毫秒),并将消息写入每个RichTextBox

您可以定义自己的数据类型,其中包含每个消息的必要信息:

Public Structure OutputMessage
    Public Color As Color?
    Public Text As String
    Public [RichTextBox] As RichTextBox
    Public ScrollToBottom As Boolean

    Public Sub New(ByVal Text As String, ByVal Color As Color?, ByVal ScrollToBottom As Boolean, ByVal [RichTextBox] As RichTextBox)
        Me.Text = Text
        Me.Color = Color
        Me.ScrollToBottom = ScrollToBottom
        Me.RichTextBox = [RichTextBox]
    End Sub
End Structure

然后以您的形式:

Private MessageQueue As New ConcurrentQueue(Of OutputMessage)

Dim WithEvents UpdateTimer As New Timer With {.Interval = 1, .Enabled = True}

Private Sub UpdateTimer_Tick(sender As Object, e As EventArgs) Handles UpdateTimer.Tick
    Dim Message As OutputMessage
    While MessageQueue.TryDequeue(Message)
        PrintMessage(Message)
    End While
End Sub

Private Sub PrintMessage(ByVal Message As OutputMessage)
    If Not Message.Color.HasValue Then
        Message.RichTextBox.SelectionColor = Color.Black
    Else
        Message.RichTextBox.SelectionColor = Message.Color.Value
    End If

    Message.RichTextBox.SelectedText = Message.Text

    If Message.ScrollToBottom Then
        Message.RichTextBox.Select(Message.RichTextBox.Text.Length - 1, 0)
        Message.RichTextBox.ScrollToCaret()
    End If
    Message.RichTextBox.AppendText(vbCrLf)
End Sub

最后,在您的线程中:

Public Sub LogInBoxOutput2(ByVal [RichTextBox] As RichTextBox, textColor As Color?, ByVal text As String, Optional logToFile As Boolean = False)

    Dim textToWrite As String = "[" & Now.ToString("dd:MM:yyyy HH:mm:ss.fff") & "] - " & text

    If logNodeValues Then
        MessageQueue.Enqueue(New OutputMessage(textToWrite, textColor, scrollToBottom, [RichTextBox]))
    End If

    If logToFile Then
        writeToFileQueue2.Enqueue(textToWrite & vbCrLf)
    End If

End Sub