Hello, please find attached a basic outline of what I am attempting to
accomplish... basically I want to create a number of THREADS (which I can do
fine), but I then need a method for them to be able to communicate with each
other, either through a message loop, or some other manner. I ALSO need to
be able to CALL specific functions / subs WITHIN a thread, based on what
another THREAD is doing... here is the attached code... WHEN I click on the
CALLOUT button, it HANGS the thread until it's execution is done:
*** This is where the issue lies - when its called from the main gui, the
thread running it blocks...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
LineArray(txtCallOutOn.Text).callout()
End Sub
***
CODE BELOW --
Imports System.Threading
Imports System.ComponentModel 'for CancelEventArgs
Imports System.Runtime.InteropServices 'COM support
Public Class Form3
Inherits System.Windows.Forms.Form
'Public WithEvents mVoiceBocx As VoiceBocxLib.VoiceBocx ' VoiceBocx control
Private iNrTrunks As Integer 'maximum number of available trunks
Private LineArray() As TrunkThread
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents txtIterations As System.Windows.Forms.TextBox
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
Friend WithEvents ToTrunk As System.Windows.Forms.TextBox
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents FromTrunk As System.Windows.Forms.TextBox
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents btnStart As System.Windows.Forms.Button
Friend WithEvents btnExit As System.Windows.Forms.Button
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents txtCallOutOn As System.Windows.Forms.TextBox
Friend WithEvents txtBridge As System.Windows.Forms.TextBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.txtIterations = New System.Windows.Forms.TextBox
Me.btnStart = New System.Windows.Forms.Button
Me.ListBox1 = New System.Windows.Forms.ListBox
Me.ToTrunk = New System.Windows.Forms.TextBox
Me.Label2 = New System.Windows.Forms.Label
Me.FromTrunk = New System.Windows.Forms.TextBox
Me.Label1 = New System.Windows.Forms.Label
Me.btnExit = New System.Windows.Forms.Button
Me.Button1 = New System.Windows.Forms.Button
Me.txtCallOutOn = New System.Windows.Forms.TextBox
Me.Button2 = New System.Windows.Forms.Button
Me.txtBridge = New System.Windows.Forms.TextBox
Me.SuspendLayout()
'
'txtIterations
'
Me.txtIterations.Location = New System.Drawing.Point(32, 48)
Me.txtIterations.Name = "txtIterations"
Me.txtIterations.TabIndex = 0
Me.txtIterations.Text = ""
'
'btnStart
'
Me.btnStart.Location = New System.Drawing.Point(160, 48)
Me.btnStart.Name = "btnStart"
Me.btnStart.Size = New System.Drawing.Size(96, 23)
Me.btnStart.TabIndex = 1
Me.btnStart.Text = "Launch Thread"
'
'ListBox1
'
Me.ListBox1.Location = New System.Drawing.Point(16, 88)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(544, 355)
Me.ListBox1.TabIndex = 4
'
'ToTrunk
'
Me.ToTrunk.Location = New System.Drawing.Point(528, 48)
Me.ToTrunk.Name = "ToTrunk"
Me.ToTrunk.Size = New System.Drawing.Size(33, 20)
Me.ToTrunk.TabIndex = 10
Me.ToTrunk.Text = "11"
'
'Label2
'
Me.Label2.Location = New System.Drawing.Point(496, 48)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(27, 21)
Me.Label2.TabIndex = 9
Me.Label2.Text = "To"
'
'FromTrunk
'
Me.FromTrunk.Location = New System.Drawing.Point(448, 48)
Me.FromTrunk.Name = "FromTrunk"
Me.FromTrunk.Size = New System.Drawing.Size(40, 20)
Me.FromTrunk.TabIndex = 8
Me.FromTrunk.Text = "0"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(376, 48)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(67, 21)
Me.Label1.TabIndex = 7
Me.Label1.Text = "Use trunks:"
'
'btnExit
'
Me.btnExit.Location = New System.Drawing.Point(272, 48)
Me.btnExit.Name = "btnExit"
Me.btnExit.Size = New System.Drawing.Size(40, 24)
Me.btnExit.TabIndex = 11
Me.btnExit.Text = "Exit"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(608, 24)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 12
Me.Button1.Text = "Button1"
'
'txtCallOutOn
'
Me.txtCallOutOn.Location = New System.Drawing.Point(608, 56)
Me.txtCallOutOn.Name = "txtCallOutOn"
Me.txtCallOutOn.Size = New System.Drawing.Size(72, 20)
Me.txtCallOutOn.TabIndex = 13
Me.txtCallOutOn.Text = "2"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(608, 96)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 14
Me.Button2.Text = "Button2"
'
'txtBridge
'
Me.txtBridge.Location = New System.Drawing.Point(608, 128)
Me.txtBridge.Name = "txtBridge"
Me.txtBridge.Size = New System.Drawing.Size(72, 20)
Me.txtBridge.TabIndex = 15
Me.txtBridge.Text = "0"
'
'Form3
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(736, 454)
Me.Controls.Add(Me.txtBridge)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.txtCallOutOn)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.btnExit)
Me.Controls.Add(Me.ToTrunk)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.FromTrunk)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.ListBox1)
Me.Controls.Add(Me.txtIterations)
Me.Controls.Add(Me.btnStart)
Me.Name = "Form3"
Me.Text = "Form3"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Try
'Dim mVoiceBocx1 As VoiceBocxLib.VoiceBocx
'mVoiceBocx1 = New VoiceBocxLib.VoiceBocx
'iNrTrunks =
mVoiceBocx1.GetInstalledChannels(VoiceBocxLib.RES_ TYPE.RES_TYPE_Trunk)
'mVoiceBocx1 = Nothing
Catch ex As Exception
Trace("Error getting installed trunks =" & ex.Message)
Return
End Try
Trace("There are " & iNrTrunks & " trunks available")
End Sub
Public Sub Trace(ByVal Text As String)
If (ListBox1.Items.Count > 800) Then
ListBox1.Items.RemoveAt(0)
End If
ListBox1.Items.Add(Text)
ListBox1.SelectedIndex = ListBox1.Items.Count - 1
End Sub
Private Sub btnLaunchThread_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnStart.Click
Dim iTrunk As Integer
Dim iToTrunk As Integer
Dim iFromTrunk As Integer
Trace("Starting threads to service trunks")
iToTrunk = ToTrunk.Text
iFromTrunk = FromTrunk.Text
If (iToTrunk > iNrTrunks - 1) Then
Trace("Last trunk to use changed to last available")
iToTrunk = iNrTrunks - 1
ToTrunk.Text = iToTrunk 'don't start more trunks then we have
ToTrunk.Invalidate()
End If
If (iFromTrunk > iToTrunk) Then
Trace("First trunk to use changed to last requested")
iFromTrunk = iToTrunk
FromTrunk.Text = iFromTrunk 'don't start more trunks then we have
FromTrunk.Invalidate()
End If
'Allocate array of LineHandler objects to keep track of
'lines so that we can shut them down properly.
'It is a good practice to check if "new" succeeded but
'it is not done here for simplicity.
ReDim LineArray(iToTrunk - iFromTrunk)
Dim Line As New TrunkThread
For iTrunk = iFromTrunk To iToTrunk
Line = New TrunkThread
LineArray(iTrunk - iFromTrunk) = Line
'pass parameters to the new thread
Line.iTrunk = iTrunk
Line.MainForm = Me
'this delegate will handle thread start event
Dim ts As ThreadStart
ts = New ThreadStart(AddressOf Line.main)
'create new thread
Dim wrkThread As Thread
wrkThread = New Thread(ts)
Line.CurrentThread = wrkThread
Trace("Starting new thread for trunk " & iTrunk)
wrkThread.ApartmentState = ApartmentState.STA 'default is MTA
wrkThread.Name = iTrunk.ToString() 'for easier tracing
wrkThread.IsBackground = True
wrkThread.Start()
Next
btnStart.Enabled = False
End Sub
Private Sub ButtonExit_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnExit.Click
'We must not exit if the call is in progress, need to check it in
Form.Closing
Close() 'Closing event for the Form is not triggered without this
End Sub
'validate from/to trunk values
Private Sub Trunk_KeyPress_From(ByVal sender As Object, ByVal e As
KeyPressEventArgs) Handles FromTrunk.KeyPress
'If not numeric, tell Windows that we handled the event.
'Backspace is allowed for corrections.
If (Not (Char.IsNumber(e.KeyChar)) And (e.KeyChar <> ChrW(8))) Then '8 is
backspace
e.Handled = True
End If
End Sub
Private Sub Trunk_KeyPress_To(ByVal sender As Object, ByVal e As
KeyPressEventArgs) Handles ToTrunk.KeyPress
'If not numeric, tell Windows that we handled the event.
'Backspace is allowed for corrections.
If (Not (Char.IsNumber(e.KeyChar)) And (e.KeyChar <> ChrW(8))) Then '8 is
backspace
e.Handled = True
End If
End Sub
Private Sub MTInboundForm_Closed(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Closed
Application.Exit()
End Sub
Private Sub MTInboundForm_Closing(ByVal sender As System.Object, ByVal e As
CancelEventArgs) Handles MyBase.Closing
e.Cancel = False 'don't cancel exit
'if lines never started
If (LineArray Is Nothing) Then
Return
End If
Dim iLineCount As Integer = LineArray.Length
Do
Dim iStillRunning As Integer = 0
Dim iLine As Integer = 0
For iLine = 0 To iLineCount - 1
'if thread already exited, continue
If (Not ((LineArray(iLine).CurrentThread) Is Nothing)) Then
LineArray(iLine).Shutdown(False)
If (Not ((LineArray(iLine).CurrentThread) Is Nothing)) Then
iStillRunning = iStillRunning + 1
End If
End If
Next
If (0 = iStillRunning) Then 'we are done
Return
End If
Dim strMsg As String = "There are still " + Str(iStillRunning) + " running
threads."
Dim Result As DialogResult = MessageBox.Show( _
strMsg + " Do you want to try again (No will force the exit as is)?", _
"Exiting Application", MessageBoxButtons.YesNo)
If (DialogResult.No = Result) Then
'force exit even if some threads not stopped yet
For iLine = 0 To iLineCount - 1
If (Not ((LineArray(iLine).CurrentThread) Is Nothing)) Then
LineArray(iLine).Shutdown(True) 'force exit
End If
Next
Return 'we are done
End If
Loop While (True)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
'LineArray(txtCallOutOn.Text).bcallout = True
LineArray(txtCallOutOn.Text).callout()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
LineArray(txtCallOutOn.Text).conf(txtBridge.Text)
LineArray(txtBridge.Text).conf(txtCallOutOn.Text)
End Sub
End Class
Class TrunkThread
'Public WithEvents mVoiceBocx As VoiceBocxLib.VoiceBocx ' VoiceBocx control
Public MainForm As Form3
Public iTrunk As Integer
Public bcallout As Boolean
Public CurrentThread As Thread
Private bincall As Boolean
Public Property test()
Get
End Get
Set(ByVal Value)
End Set
End Property
Public Sub main()
Dim iThreadId As Integer
iThreadId = Thread.CurrentThread.GetHashCode()
MainForm.Trace("In the new thread " & iThreadId & " on trunk " & iTrunk)
Try
'mVoiceBocx = New VoiceBocxLib.VoiceBocx
MainForm.Trace("Voice Object instantiated on trunk " & iTrunk)
'mVoiceBocx.TrunkAssign(iTrunk)
MainForm.Trace("Trunk assigned " & iTrunk)
Catch e As COMException
MainForm.Trace("Error starting Voice Object =" & (e.ErrorCode And 65535))
Return
Catch e As Exception
MainForm.Trace("Error using Voice Object =" & e.Message)
Return
End Try
MainForm.Trace("Incoming call handler set on trunk " & iTrunk)
Application.Run()
End Sub
Public Sub callout()
MainForm.Trace("OutDial for trunk " & iTrunk)
Try
'mVoiceBocx.MakeCall("474-7031", True)
MainForm.Trace("Playing greeting on trunk " & iTrunk)
'mVoiceBocx.PlayFile("hello.vox",
VoiceBocxLib.SOUNDFILE_TYPE.SOUNDFILE_TYPE_Vox24K)
Do
Thread.CurrentThread.Sleep(100)
Loop
Catch e As COMException
Dim iCode As Integer
iCode = e.ErrorCode And 65535
'If (mVoiceBocx.ErrorNumber = iCode) Then
'MainForm.Trace("Hangup detected on trunk " & iTrunk)
'Else
' MainForm.Trace("Call processing ended with code " & iCode)
'End If
Finally
Try
MainForm.Trace("Disconnecting on trunk " & iTrunk)
'mVoiceBocx.DisconnectCall()
Catch e As COMException
MainForm.Trace("Exception " & (e.ErrorCode And 65535) & "on trunk " &
iTrunk)
End Try
bincall = False
MainForm.Trace("Ready for calls on trunk " & iTrunk)
End Try
End Sub
Public Sub conf(ByVal iWho As Integer)
MainForm.Trace("Conf for trunk " & iTrunk)
Try
'mVoiceBocx.TrunkListenTo(VoiceBocxLib.RES_TYPE.RE S_TYPE_Trunk, iWho)
MainForm.Trace("Conf " & iTrunk & " and " & iWho)
Do
Thread.CurrentThread.Sleep(100)
Loop
Catch e As COMException
Dim iCode As Integer
iCode = e.ErrorCode And 65535
'If (mVoiceBocx.ErrorNumber = iCode) Then
'MainForm.Trace("Hangup detected on trunk " & iTrunk)
'Else
' MainForm.Trace("Call processing ended with code " & iCode)
'End If
Finally
Try
MainForm.Trace("Disconnecting on trunk " & iTrunk)
'mVoiceBocx.DisconnectCall()
Catch e As COMException
MainForm.Trace("Exception " & (e.ErrorCode And 65535) & "on trunk " &
iTrunk)
End Try
bincall = False
MainForm.Trace("Ready for calls on trunk " & iTrunk)
End Try
End Sub
Public Sub Shutdown(ByVal bForceExit As Boolean)
If (bincall And (False = bForceExit)) Then
Return
End If
'mVoiceBocx.TrunkUnassign()
'mVoiceBocx.MediaUnassign()
CurrentThread.Abort()
CurrentThread = Nothing
End Sub
Private Sub mVoiceBocx_IncomingCall() 'Handles mVoiceBocx.IncomingCall
bincall = True
Try
MainForm.Trace("Rings for trunk " & iTrunk)
'mVoiceBocx.AnswerCall()
MainForm.Trace("Playing greeting on trunk " & iTrunk)
'mVoiceBocx.PlayFile("hello.vox",
VoiceBocxLib.SOUNDFILE_TYPE.SOUNDFILE_TYPE_Vox24K)
Do
Thread.CurrentThread.Sleep(100)
Loop
Catch e As COMException
Dim iCode As Integer
iCode = e.ErrorCode And 65535
'If (mVoiceBocx.ErrorNumber = iCode) Then
'MainForm.Trace("Hangup detected on trunk " & iTrunk)
'Else
' MainForm.Trace("Call processing ended with code " & iCode)
'End If
Finally
Try
MainForm.Trace("Disconnecting on trunk " & iTrunk)
'mVoiceBocx.DisconnectCall()
Catch e As COMException
MainForm.Trace("Exception " & (e.ErrorCode And 65535) & "on trunk " &
iTrunk)
End Try
bincall = False
MainForm.Trace("Ready for calls on trunk " & iTrunk)
End Try
End Sub 'incoming call
Private Sub mVoiceBocx_CallerHangUp() 'Handles mVoiceBocx.CallerHangUp
MainForm.Trace("Caller hungup " & iTrunk)
End Sub
End Class