我有一个具有8个线程的应用程序。该应用程序的主要功能是显示4个输出的实时信息,并将信息写入文件。
现在,我对多线程领域了解不多,但是我已经成功创建了4个线程,如果我不将信息记录到富文本框中,则它们工作正常,他们会编写信息放入文件中。
我的问题是:我可以在同一窗体(MainForm)上显示每个输出的实时信息吗? 输出彼此独立工作
以下是我用于将信息登录到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中是否有类似的内容,您可以仅刷新页面的一帧/一部分(意味着仅调用主窗体的一部分)?
谢谢
答案 0 :(得分:1)
除了应该调用之外,还应该将所有要输出到UI的消息排入队列,以使UI和处理器得到一些休息。然后使用System.Windows.Forms.Timer
和Interval
为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