By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,989 Members | 2,392 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,989 IT Pros & Developers. It's quick & easy.

multithreading problem - help!

P: n/a
Hi all,

I'm trying to program a multithreaded application - it currently
works, but I have two problems. I'm relatively new to VB.NET (C and
VB6 are my things) so I'm a bit lost here. The code is based on the
countdown / controlinvoker quickstart at GotDotNet.com.

The problems are:

(1) There's a memory leak somewhere. I don't know where, but it's
probably something stupid I've done when I added a second thread.

(2) How do I set it up to exit gracefully (i.e. where in the
application should I set threadsRunning = FALSE); at the moment even
when in debug mode it crashes when stopping - I assume because I
haven't sewn things up properly.

The basics of the thread architecture are below. I've added a second
thread to the quickstart code, and I've added a second ControlInvoker
instance. With regard to the two threads, one updates the screen and
the other communicates with a data comms interface, and passes some of
this data to the serial port. The communications routine should take
priority over the screen updating.

Can anyone cast an expert eye over it and tell me where I'm being
thick?

Thanks
Andy

===========================

' main application class:
Public Class Form1
Inherits System.Windows.Forms.Form
Private thrComms As Thread
Private thrDisplayUpdate As Thread
Private threadsRunning As Boolean
Private controlInvoker As controlInvoker
Private controlInvoker2 As controlInvoker

' ...

Public Sub New()

MyBase.New()

Try
'This call is required by the Windows Form Designer.
InitializeComponent()
Catch ex As Exception
Stop
End Try
' InitialiseSerialPort()

'Me.CreateGraphics()
'Add any initialization after the InitializeComponent() call

Me.thrComms = New Thread(New ThreadStart(AddressOf
Me.Thread_232))
Me.thrDisplayUpdate = New Thread(New ThreadStart(AddressOf
Me.Thread_DisplayUpdate))

controlInvoker = New ControlInvoker(Me)
controlInvoker2 = New ControlInvoker(Me)

Me.thrComms.Priority = ThreadPriority.AboveNormal
Me.thrDisplayUpdate.Priority = ThreadPriority.Normal

Me.thrComms.Start()
Me.thrDisplayUpdate.Start()

Me.threadsRunning = True
End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
MyBase.Dispose(disposing)
End Sub
' ....

Public Sub Thread_232()
' Data comms worker thread

Dim rxmsg_counter As Integer
Dim messages As sPCCanMsg

Dim temp_sec_value As Integer

controlInvoker = New ControlInvoker(Me)
'worker thread

Do
msg_list_size = 50
controlInvoker.Invoke(New MethodCallInvoker(AddressOf
interface_read_Wrapper))
' get 50 messages
If (returned_status = HTX_SUCCESS) Then
' do processing
End If

'...
If cycle_count > 50 Then

' reset interface
'Thread.Sleep(1)
controlInvoker.Invoke(New
MethodCallInvoker(AddressOf interface_stop_Wrapper))

'Thread.Sleep(1)
controlInvoker.Invoke(New
MethodCallInvoker(AddressOf interface_start_Wrapper))

cycle_count = 0
End If

Loop While Me.threadsRunning

End Sub
Public Sub Thread_display()
controlInvoker2 = New ControlInvoker(Me)
Do
controlInvoker2.Invoke(New MethodCallInvoker(AddressOf
update_display_wrapper))
Loop While Me.threadRunning
End Sub
Private Sub update_display_wrapper(ByVal arguments() As Object)
'----- Start the Display task
' Gets data from Global Variables, scales data and updates the screen.

' ......do lots of screen updating....

End Sub
Private Sub interface_start_wrapper(ByVal arguments() As Object)
canstatus2 = InterfaceStart(1) ' DLL call to start the data comms
interface
End Sub
Private Sub interface_stop_wrapper(ByVal arguments() As Object)
canstatus2 = InterfaceStop(1)' DLL call to stop the data comms
interface
End Sub

Private Sub interface_read_wrapper(ByVal arguments() As Object)
canstatus2 = InterfaceReadEx(1, msg_list(0), 5, 50)' DLL call to
read 50 messages from data comms interface
End Sub

End Class

=====================================

'''' CONTROLINVOKER CLASS ''''

Imports System
Imports System.Collections
Imports System.Windows.Forms
Public Delegate Sub MethodCallInvoker(ByVal o() As Object)

' Control.Invoke allows a method to be invoked on the same thread as
the one
' the control was created on. Unlike in the full .NET Framework, the
..NET
' Compact Framework does not support the Control.Invoke overload for
passing an
' array of objects to pass as arguments. This ControlInvoker class
overcomes
' this limitation.
Public Class ControlInvoker

Private Class MethodCall
Public invoker As MethodCallInvoker
Public arguments() As Object
Public Sub New(ByVal invoker As MethodCallInvoker, ByVal
arguments() As Object)
Me.invoker = invoker
Me.arguments = arguments
End Sub 'New
End Class 'MethodCall

Private control As Control
Private argumentInvokeList As New Queue
' The constructor typically takes a form
Public Sub New(ByVal control As Control)
Me.control = control
End Sub 'New
' The delegate wrapping the method and its arguments
' to be called on the same thread as the control.
Public Sub Invoke(ByVal invoker As MethodCallInvoker, ByVal
ParamArray arguments() As Object)

Me.argumentInvokeList.Enqueue(New MethodCall(invoker,
arguments))

control.Invoke(New EventHandler(AddressOf ControlInvoke))

End Sub 'Invoke
Private Sub ControlInvoke(ByVal sender As Object, ByVal e As
EventArgs)
Dim methodCall As MethodCall =
CType(argumentInvokeList.Dequeue(), MethodCall)
Try
methodCall.invoker(methodCall.arguments)
Catch ex As Exception
Debug.Assert(False)

End Try

End Sub 'ControlInvoke
End Class 'ControlInvoker
Nov 20 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.