Mutlithreading InfoMessagBox by ConcurrentQueue, Interlocked and Timer.
In one threading application for information message I using that solution How to intercept exception & console output & debug trace and show it in textbox, but in muttithreading application I usually show information message in this way Оновлення StatusLabel з потоку BackGroundWorker - приклад застосування Action, Delegate, Invoke, AddressOf, Extension, Expression or by the code I descripted below.
136: #Region "InfoMessage"
137:
138: Dim InfoMessageQueue As ConcurrentQueue(Of String) = New ConcurrentQueue(Of String)
139: Dim MessageCount As Integer = 0
140:
141: Public Sub InfoMessage(Msg As String)
142: Me.InvokeOnUiThreadIfRequired(Sub()
143:
144: Threading.Interlocked.Increment(MessageCount)
145: If InfoCheckBox.Checked Then
146: InfoMessageQueue.Enqueue(MessageCount.ToString & ": " & Msg & vbCrLf)
147: End If
148: End Sub)
149: End Sub
150:
151: Dim WithEvents Timer1 As Timers.Timer
152: Sub StartTimer()
153: Timer1 = New Timer(1000)
154: Timer1.Enabled = True
155: Timer1.Start()
156: End Sub
157:
158: Sub StopTimer()
159: Timer1.Enabled = False
160: Timer1.Stop()
161: End Sub
162:
163:
164:
165: Private Sub Timer1_Elapsed(sender As Object, e As ElapsedEventArgs) Handles Timer1.Elapsed
166: Me.InvokeOnUiThreadIfRequired(Sub()
167: TimeLabel.Text += Timer1.Interval / 1000
168: TimeLabel.Refresh()
169: End Sub)
170: Me.InvokeOnUiThreadIfRequired(Sub()
171: Message.Text = ""
172: Dim OneItem As String = ""
173: If InfoCheckBox.Checked Then
174: While (Not InfoMessageQueue.IsEmpty)
175: InfoMessageQueue.TryDequeue(OneItem)
176: Message.Text &= OneItem
177: End While
178: Message.SelectionStart = Message.TextLength
179: Message.ScrollToCaret()
180: Message.Refresh()
181: End If
182: End Sub)
183: End Sub
184:
185: #End Region
This is not full correct code, it's possible to doubling message number, because Threading.Interlocked.Increment and InfoMessageQueue.Enqueue is not atomic operation, more correctly way to use class Monitor, SyncLock statement or <Runtime.CompilerServices.MethodImplAttribute(Runtime.CompilerServices.MethodImplOptions.Synchronized)> attribute for needed method.
But in this case this unblocked code is a best way.
|