A few days ago, I ran into the problem of how to display logging or status info in the user interface when the log messages are generated in a different thread. I found a result that seems to work satisfactorily at the moment.
I'm going to give the example in VB .NET but it will work easily in C# also.
First off, create a simple delegate:
Public Delegate Sub LogSafeCall(ByVal s As String)
Then create a Sub to provide thread safety. I will use a listbox in this example but you could also use a textbox. The reason for choosing the listbox is due to the fact that it stores strings in a collection. A textbox would require appending to the text property, and...since strings are immutable, this would create many seperate strings in memory.
Here's the Threadsafe logging function, m_console is a listbox control:
Private Sub Log(ByVal s As String)
If (m_console.InvokeRequired) Then
Dim d As LogSafeCall = New LogSafeCall(AddressOf Log)
m_console.Invoke(d, s)
Else
m_console.Items.Add(s)
'if you wish to have the last item selected then uncomment the following:
'm_console.SelectedIndex = m_console.Items.Count - 1
End If
End Sub
Since I wanted to Log in a file as well as display the messages into the textbox, I created the following class and inherited the TextWriter streaming class So here is the complete code:
Option Explicit On
Option Strict On
Imports System.IO
Imports System.Windows.Forms
Public Delegate Sub LogSafeCall(ByVal s As String)
Public Class ListBoxWriter
Inherits TextWriter
Private m_console As ListBox
Public Sub New(ByVal console As ListBox)
m_console = console
End Sub
Public Overrides ReadOnly Property Encoding() As System.Text.Encoding
Get
Return System.Text.Encoding.ASCII
End Get
End Property
Public Overrides Sub WriteLine(ByVal value As String)
MyBase.WriteLine(value)
Log(value)
End Sub
Private Sub Log(ByVal s As String)
If (m_console.InvokeRequired) Then
Dim d As LogSafeCall = New LogSafeCall(AddressOf Log)
m_console.Invoke(d, s)
Else
m_console.Items.Add(s)
'm_console.SelectedIndex = m_console.Items.Count - 1
End If
End Sub
End Class