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

Thread blocking diagnosis

P: n/a
Bob
Hi,
I have an app that has a 3rd party phone answering control (4 of )
(interfacing with dialogic 4 line card) attached to the main form.
each control raises an event when its Dialogic line detects ring tone.
I use the ring detect event handler to create a new thread which is given a
reference to the control that is being rung. The called method then
interacts with the control until the call finishes.
My problem is that I believe I am getting thread blocking between the
threads that are dealing with the calls.
There doesn't appear to be any consistent pattern to the blocking and I was
wondering what techniques I can use to further investigate this. I have run
the app under a commercial profiler but there is nothing definitive showing.
Each of the phone call threads seem to get roughly the same time.
The blocking occurs when the phone handling objects are getting input from
phone users. (DTMF tones) but varies at which point it occurs.

Initiating Code from one of the four ring detect event handlers follows:
telecall te = new telecall();//Class that contains state engine to handle
call

te.TraceMessage += new telecall.TraceMessageEventHandler(te_TraceMessage) ;//
info back from state engine

te.LineStateChange += new
telecall.LineStateChangeEventHandler(this.SetLineS tatus); // Phone line
status back from state engine

te.MyForm = this;//Ref to stop orphans

te.Vbocx = ((AxVbocxLibrary.AxVBocx)(sender));//Assigning ref to the line
handling object.

ThreadStart ts = new ThreadStart(te.HandleCall);// State engine

Thread t = new Thread(ts);

t.Name = "PH1";

t.SetApartmentState(ApartmentState.STA);//desperation

t.Start();
Oct 10 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a

Bob wrote:
Hi,
I have an app that has a 3rd party phone answering control (4 of )
(interfacing with dialogic 4 line card) attached to the main form.
each control raises an event when its Dialogic line detects ring tone.
I use the ring detect event handler to create a new thread which is given a
reference to the control that is being rung. The called method then
interacts with the control until the call finishes.
My problem is that I believe I am getting thread blocking between the
threads that are dealing with the calls.
There doesn't appear to be any consistent pattern to the blocking and I was
wondering what techniques I can use to further investigate this. I have run
the app under a commercial profiler but there is nothing definitive showing.
Each of the phone call threads seem to get roughly the same time.
The blocking occurs when the phone handling objects are getting input from
phone users. (DTMF tones) but varies at which point it occurs.

Initiating Code from one of the four ring detect event handlers follows:
telecall te = new telecall();//Class that contains state engine to handle
call

te.TraceMessage += new telecall.TraceMessageEventHandler(te_TraceMessage) ;//
info back from state engine

te.LineStateChange += new
telecall.LineStateChangeEventHandler(this.SetLineS tatus); // Phone line
status back from state engine

te.MyForm = this;//Ref to stop orphans

te.Vbocx = ((AxVbocxLibrary.AxVBocx)(sender));//Assigning ref to the line
handling object.

ThreadStart ts = new ThreadStart(te.HandleCall);// State engine

Thread t = new Thread(ts);

t.Name = "PH1";

t.SetApartmentState(ApartmentState.STA);//desperation

t.Start();
>From the COM library reference, it appears that you are using an older
version of CallSuite... Those are STA Com Objects, and as such each
one must exist on it's own thread or you need to use the async methods
methods provided by the control or they will block each other. One way
I have over come this, is to write a wrapper class for the VoiceBocx
object that spawns a thread in the constructor. that intializes the
object and then calls Application.Run. I use a ManualReset Event to
signal that intialization has completed. It is complex I guess, but it
works well. I use a newer version - 9.1, and I don't use the ActiveX
control - only the object, but this code was written with the older
version originally. The code here is not all of the code, nor is it
actually working code - it is just a bit to illustrate the point:

public sealed class Trunk : System.IDisposable
{
private ADXVoiceClass trunk;
private ManualResetEvent intialized;
private Exception startup;

public Trunk(int channel)
{
this.startup = null;

/ set this so that we can signal initilization...
this.intialized = new ManualResetEvent(false);

// VoiceBocx objects need to exist on their own thread to
// avoid blocking problems. So, we will create an STA Thread,
// create the object and start a message pump for the object.
Thread runner = new Thread (new ThreadStart(this.ObjectThread));
runner.ApartmentState = ApartmentState.STA;
runner.IsBackground = true;
runner.Start ();

// wait for intialization to complete.
this.intialized.WaitOne();
this.intialized.Close();
if (this.startup != null)
{
throw this.startup;
}
}

private void ObjectThread()
{
try
{
// set up the trunk object
InitializeTrunkObject();

// signal the parent!
this.intialized.Set();

// start a message loop for COM events on this thread
Application.Run();
}
catch (Exception ex)
{
this.startup = ex;
this.intialized.Set ();
}
}

..... Lots of other junk
}

The actual working code actually lets you pass in a value to determine
if it creates a thread for the object or not. I am not saying this is
the only (or even the best way), but if you want to use multiple phone
lines in your application, then you will need to use the async model
supported by the VoiceBocx control or arrange to have each line live on
it's own thread.

Anyway,
HTH

--
Tom Shelton

Oct 10 '06 #2

P: n/a

Tom Shelton wrote:
Bob wrote:
Hi,
I have an app that has a 3rd party phone answering control (4 of )
(interfacing with dialogic 4 line card) attached to the main form.
each control raises an event when its Dialogic line detects ring tone.
I use the ring detect event handler to create a new thread which is given a
reference to the control that is being rung. The called method then
interacts with the control until the call finishes.
My problem is that I believe I am getting thread blocking between the
threads that are dealing with the calls.
There doesn't appear to be any consistent pattern to the blocking and I was
wondering what techniques I can use to further investigate this. I have run
the app under a commercial profiler but there is nothing definitive showing.
Each of the phone call threads seem to get roughly the same time.
The blocking occurs when the phone handling objects are getting input from
phone users. (DTMF tones) but varies at which point it occurs.
By the way, if this is CallSuite - there is a bug in the GetDigits
call. It will always pause 3 seconds, even if you tell it to return
immediately. The only way around it that I have found is to implement
my own digit buffer using the DigitDetected event.

--
Tom Shelton

Oct 10 '06 #3

P: n/a
Bob
Hi Tom,
Thank you for the example,
Yes, using 5.2. The penny finally dropped that although I was spawing new
threads ultimately they were refering back to the 4 controls on the parent
form. I have taken a slightly more expensive way in that I now have a form
with only one control on it and I spawn 4 of these, hide them and have them
report back to the main form via events.
Load test today. (Heres hoping:-))
regards
Bob
"Tom Shelton" <to*@mtogden.comwrote in message
news:11*********************@k70g2000cwa.googlegro ups.com...
>
Bob wrote:
Hi,
I have an app that has a 3rd party phone answering control (4 of )
(interfacing with dialogic 4 line card) attached to the main form.
each control raises an event when its Dialogic line detects ring tone.
I use the ring detect event handler to create a new thread which is
given a
reference to the control that is being rung. The called method then
interacts with the control until the call finishes.
My problem is that I believe I am getting thread blocking between the
threads that are dealing with the calls.
There doesn't appear to be any consistent pattern to the blocking and I
was
wondering what techniques I can use to further investigate this. I have
run
the app under a commercial profiler but there is nothing definitive
showing.
Each of the phone call threads seem to get roughly the same time.
The blocking occurs when the phone handling objects are getting input
from
phone users. (DTMF tones) but varies at which point it occurs.

Initiating Code from one of the four ring detect event handlers follows:
telecall te = new telecall();//Class that contains state engine to
handle
call

te.TraceMessage += new
telecall.TraceMessageEventHandler(te_TraceMessage) ;//
info back from state engine

te.LineStateChange += new
telecall.LineStateChangeEventHandler(this.SetLineS tatus); // Phone line
status back from state engine

te.MyForm = this;//Ref to stop orphans

te.Vbocx = ((AxVbocxLibrary.AxVBocx)(sender));//Assigning ref to the
line
handling object.

ThreadStart ts = new ThreadStart(te.HandleCall);// State engine

Thread t = new Thread(ts);

t.Name = "PH1";

t.SetApartmentState(ApartmentState.STA);//desperation

t.Start();
From the COM library reference, it appears that you are using an older
version of CallSuite... Those are STA Com Objects, and as such each
one must exist on it's own thread or you need to use the async methods
methods provided by the control or they will block each other. One way
I have over come this, is to write a wrapper class for the VoiceBocx
object that spawns a thread in the constructor. that intializes the
object and then calls Application.Run. I use a ManualReset Event to
signal that intialization has completed. It is complex I guess, but it
works well. I use a newer version - 9.1, and I don't use the ActiveX
control - only the object, but this code was written with the older
version originally. The code here is not all of the code, nor is it
actually working code - it is just a bit to illustrate the point:

public sealed class Trunk : System.IDisposable
{
private ADXVoiceClass trunk;
private ManualResetEvent intialized;
private Exception startup;

public Trunk(int channel)
{
this.startup = null;

/ set this so that we can signal initilization...
this.intialized = new ManualResetEvent(false);

// VoiceBocx objects need to exist on their own thread to
// avoid blocking problems. So, we will create an STA Thread,
// create the object and start a message pump for the object.
Thread runner = new Thread (new ThreadStart(this.ObjectThread));
runner.ApartmentState = ApartmentState.STA;
runner.IsBackground = true;
runner.Start ();

// wait for intialization to complete.
this.intialized.WaitOne();
this.intialized.Close();
if (this.startup != null)
{
throw this.startup;
}
}

private void ObjectThread()
{
try
{
// set up the trunk object
InitializeTrunkObject();

// signal the parent!
this.intialized.Set();

// start a message loop for COM events on this thread
Application.Run();
}
catch (Exception ex)
{
this.startup = ex;
this.intialized.Set ();
}
}

.... Lots of other junk
}

The actual working code actually lets you pass in a value to determine
if it creates a thread for the object or not. I am not saying this is
the only (or even the best way), but if you want to use multiple phone
lines in your application, then you will need to use the async model
supported by the VoiceBocx control or arrange to have each line live on
it's own thread.

Anyway,
HTH

--
Tom Shelton

Oct 10 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.