I have a multi threaded windows form application that runs great after
calling Application.Run(). Application.Run is required for a COM component
I a using in the app (required for message loop). I have created a windows
service from VStudio 2005 template. What is the windows service replacement
for Application.Run()? 28 7127
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
ServiceBase.Run(new service_class); maybe,
but you have to write class (service_class) with OnStart (here you must
call your main code) , OnPause, OnStop methods that inherites
System.ServiceProcess.ServiceBase
D
Thanks a lot. I have tried, however, no luck. For some reason this com
component just wont function without application.run... which wont work in
the win service.
"Dubravko Sever" <Du******************@foi.hrwrote in message
news:f2**********@news1.carnet.hr...
>
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
ServiceBase.Run(new service_class); maybe,
but you have to write class (service_class) with OnStart (here you must
call your main code) , OnPause, OnStop methods that inherites
System.ServiceProcess.ServiceBase
D
Have you check your account does it have enough permissions? Try to run your
service as a administrator just for testing.
D
<msnews.microsoft.comwrote in message
news:eV**************@TK2MSFTNGP06.phx.gbl...
Thanks a lot. I have tried, however, no luck. For some reason this com
component just wont function without application.run... which wont work in
the win service.
"Dubravko Sever" <Du******************@foi.hrwrote in message
news:f2**********@news1.carnet.hr...
>> <msnews.microsoft.comwrote in message news:Oc*************@TK2MSFTNGP06.phx.gbl...
>>>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
ServiceBase.Run(new service_class); maybe, but you have to write class (service_class) with OnStart (here you must call your main code) , OnPause, OnStop methods that inherites System.ServiceProcess.ServiceBase
D
A Windows service can be started from the command line using Net Start
<yourServiceNameor Net Stop <yourServiceName>. The easiest is to use the
Services MMC.
"msnews.microsoft.com" wrote:
I have a multi threaded windows form application that runs great after
calling Application.Run(). Application.Run is required for a COM component
I a using in the app (required for message loop). I have created a windows
service from VStudio 2005 template. What is the windows service replacement
for Application.Run()?
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
No, Application.Run is not required for COM (apartment style of objects),
all you need is to do is initialize the thread that creates your COM
component to enter the STA, that means you need to set the ApartmentState to
STA before starting the thread, that way you are sure the component runs on
the same thread as the caller and no marshaling is needed.
However, you need to make sure you aren't calling any blocking wait, only
pumping waits are pumping COM messages, this is required to let the
Finalizer thread (running in the MTA) to marshal calls into the STA thread
whenever your RCW needs to be released.
Willy.
Thanks. Everything within the service runs fine (I write text to a text
file for instance). Only problem is, without application.run, the com
component reference does not function.
"Dubravko Sever" <Du******************@foi.hrwrote in message
news:f2**********@news1.carnet.hr...
Have you check your account does it have enough permissions? Try to run
your service as a administrator just for testing.
D
<msnews.microsoft.comwrote in message
news:eV**************@TK2MSFTNGP06.phx.gbl...
>Thanks a lot. I have tried, however, no luck. For some reason this com component just wont function without application.run... which wont work in the win service.
"Dubravko Sever" <Du******************@foi.hrwrote in message news:f2**********@news1.carnet.hr...
>>> <msnews.microsoft.comwrote in message news:Oc*************@TK2MSFTNGP06.phx.gbl... I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
ServiceBase.Run(new service_class); maybe, but you have to write class (service_class) with OnStart (here you must call your main code) , OnPause, OnStop methods that inherites System.ServiceProcess.ServiceBase
D
Thank you. Threading is STA. Here is an excert of the code that works fine
as a windows form... But, for some reason I can not put it together to work
as a service.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.InteropServices;
using Envox.ADXVoice;
using System.Data.SqlClient;
using System.Configuration;
namespace AnsweringSystem
{
public partial class Form1 : Form
{
private LineHandler[] LineArray;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int iFromChannel = 0;
int iToChannel = 3; //4 channels
LineArray = new LineHandler[iToChannel - iFromChannel + 1];
for (int iChannel = iFromChannel; iChannel <= iToChannel;
iChannel++)
{
LineHandler Line = new LineHandler();
LineArray[iChannel - iFromChannel] = Line;
Line.iChannel = iChannel;
ThreadStart ts = new ThreadStart(Line.ProcessingThread);
Thread wrkThread = new Thread(ts);
Line.CurrentThread = wrkThread;
wrkThread.SetApartmentState(ApartmentState.STA);
wrkThread.Name = iChannel.ToString();
wrkThread.Start();
}
}
//Main class to handle individual channels on separate threads
private class LineHandler
{
public int iChannel = -1;
public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread()
{
try
{
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iChannel);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
}
catch (COMException e)
{
ADXVoice1 = null;
return;
}
catch (Exception e)
{
ADXVoice1 = null;
return;
}
//Start message loop (keeps thread from exiting and allows
ADX to process events, including state changes)
Application.Run();
Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1
eligible for garbage collection
GC.Collect(); //force Garbage Collection
GC.WaitForPendingFinalizers(); //wait for completion
}
private void OnIncomingCall()
{
//code here to play prompts, branch to other methods, etc.
}
} //End LineHandler class
}
}
I very much appreciate any advice you may have. Thank you very much.
Jay
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:A3**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
No, Application.Run is not required for COM (apartment style of objects),
all you need is to do is initialize the thread that creates your COM
component to enter the STA, that means you need to set the ApartmentState
to STA before starting the thread, that way you are sure the component
runs on the same thread as the caller and no marshaling is needed.
However, you need to make sure you aren't calling any blocking wait, only
pumping waits are pumping COM messages, this is required to let the
Finalizer thread (running in the MTA) to marshal calls into the STA thread
whenever your RCW needs to be released.
Willy.
<msnews.microsoft.comwrote in message
news:Oi**************@TK2MSFTNGP03.phx.gbl...
Thank you. Threading is STA. Here is an excert of the code that works
fine as a windows form... But, for some reason I can not put it together
to work as a service.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.InteropServices;
using Envox.ADXVoice;
using System.Data.SqlClient;
using System.Configuration;
namespace AnsweringSystem
{
public partial class Form1 : Form
{
private LineHandler[] LineArray;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int iFromChannel = 0;
int iToChannel = 3; //4 channels
LineArray = new LineHandler[iToChannel - iFromChannel + 1];
for (int iChannel = iFromChannel; iChannel <= iToChannel;
iChannel++)
{
LineHandler Line = new LineHandler();
LineArray[iChannel - iFromChannel] = Line;
Line.iChannel = iChannel;
ThreadStart ts = new ThreadStart(Line.ProcessingThread);
Thread wrkThread = new Thread(ts);
Line.CurrentThread = wrkThread;
wrkThread.SetApartmentState(ApartmentState.STA);
wrkThread.Name = iChannel.ToString();
wrkThread.Start();
}
}
//Main class to handle individual channels on separate threads
private class LineHandler
{
public int iChannel = -1;
public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread()
{
try
{
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iChannel);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
}
catch (COMException e)
{
ADXVoice1 = null;
return;
}
catch (Exception e)
{
ADXVoice1 = null;
return;
}
//Start message loop (keeps thread from exiting and allows
ADX to process events, including state changes)
Application.Run();
Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1
eligible for garbage collection
GC.Collect(); //force Garbage Collection
GC.WaitForPendingFinalizers(); //wait for completion
}
private void OnIncomingCall()
{
//code here to play prompts, branch to other methods, etc.
}
} //End LineHandler class
}
}
I very much appreciate any advice you may have. Thank you very much.
It looks like you are using an ActiveX Component, now AX was in general not
designed to be used from a service, make them work is in general a pain in
the a**, the problem is with the callbacks that arrive on anything but the
callers thread, that is they end on the thread pool threads which are MTA
and as such they need to be marshaled to the STA thread, that means you
need to pump Windows messages (not COM message), but services are not
designed to pump a message queue, only Windows applications are, you see the
dilemma?
I would suggest you to try to run this from a Console application first,
it's much easier to debug, and look how far you get before you drop this
into a service.
Willy.
Thanks Willy. I will try the console approach, however, still need to solve
the windows service dilema. For whatever reason the app runs perfectly as a
windows form but not as a windows service. And, when I remove
application.run from the windows form the app no longer runs. Any idea if
there is anything else I can try to get this functioning as a service?
Thank you very much. I really appreciate your help.
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:04**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:Oi**************@TK2MSFTNGP03.phx.gbl...
>Thank you. Threading is STA. Here is an excert of the code that works fine as a windows form... But, for some reason I can not put it together to work as a service.
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; using System.Runtime.InteropServices; using Envox.ADXVoice; using System.Data.SqlClient; using System.Configuration;
namespace AnsweringSystem { public partial class Form1 : Form { private LineHandler[] LineArray;
public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { int iFromChannel = 0; int iToChannel = 3; //4 channels
LineArray = new LineHandler[iToChannel - iFromChannel + 1];
for (int iChannel = iFromChannel; iChannel <= iToChannel; iChannel++) { LineHandler Line = new LineHandler(); LineArray[iChannel - iFromChannel] = Line; Line.iChannel = iChannel; ThreadStart ts = new ThreadStart(Line.ProcessingThread); Thread wrkThread = new Thread(ts); Line.CurrentThread = wrkThread; wrkThread.SetApartmentState(ApartmentState.STA); wrkThread.Name = iChannel.ToString(); wrkThread.Start(); } }
//Main class to handle individual channels on separate threads private class LineHandler { public int iChannel = -1; public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread() { try { ADXVoice1 = new ADXVoiceClass(); ADXVoice1.TrunkAssign(iChannel); ADXVoice1.IncomingCall += new _IADXVoiceEvents_IncomingCallEventHandler(OnIncom ingCall); } catch (COMException e) { ADXVoice1 = null; return; } catch (Exception e) { ADXVoice1 = null; return; }
//Start message loop (keeps thread from exiting and allows ADX to process events, including state changes) Application.Run();
Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1 eligible for garbage collection GC.Collect(); //force Garbage Collection GC.WaitForPendingFinalizers(); //wait for completion }
private void OnIncomingCall() { //code here to play prompts, branch to other methods, etc. }
} //End LineHandler class
} }
I very much appreciate any advice you may have. Thank you very much.
It looks like you are using an ActiveX Component, now AX was in general
not designed to be used from a service, make them work is in general a
pain in the a**, the problem is with the callbacks that arrive on anything
but the callers thread, that is they end on the thread pool threads which
are MTA and as such they need to be marshaled to the STA thread, that
means you need to pump Windows messages (not COM message), but services
are not designed to pump a message queue, only Windows applications are,
you see the dilemma?
I would suggest you to try to run this from a Console application first,
it's much easier to debug, and look how far you get before you drop this
into a service.
Willy.
What does the COM component do? Was it written in-house or is it an outside
product?
If in-house, obviously I'm going to ask if you can rewrite it in .NET. But
since that's probably not the case...what if you wrap the COM component in a
..NET console app, and call the .NET console app from your windows service?
I've never tried it...just an idea off the top of my head.
--
Brian Schwartz
FishNet Components http://www.fishnetcomponents.com
Fish Grid .NET Light: Powerful Layouts for Small Datasets
<msnews.microsoft.comwrote in message
news:e8**************@TK2MSFTNGP06.phx.gbl...
Thanks Willy. I will try the console approach, however, still need to
solve the windows service dilema. For whatever reason the app runs
perfectly as a windows form but not as a windows service. And, when I
remove application.run from the windows form the app no longer runs. Any
idea if there is anything else I can try to get this functioning as a
service? Thank you very much. I really appreciate your help.
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:04**********************************@microsof t.com...
><msnews.microsoft.comwrote in message news:Oi**************@TK2MSFTNGP03.phx.gbl...
>>Thank you. Threading is STA. Here is an excert of the code that works fine as a windows form... But, for some reason I can not put it together to work as a service.
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; using System.Runtime.InteropServices; using Envox.ADXVoice; using System.Data.SqlClient; using System.Configuration;
namespace AnsweringSystem { public partial class Form1 : Form { private LineHandler[] LineArray;
public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { int iFromChannel = 0; int iToChannel = 3; //4 channels
LineArray = new LineHandler[iToChannel - iFromChannel + 1];
for (int iChannel = iFromChannel; iChannel <= iToChannel; iChannel++) { LineHandler Line = new LineHandler(); LineArray[iChannel - iFromChannel] = Line; Line.iChannel = iChannel; ThreadStart ts = new ThreadStart(Line.ProcessingThread); Thread wrkThread = new Thread(ts); Line.CurrentThread = wrkThread; wrkThread.SetApartmentState(ApartmentState.STA); wrkThread.Name = iChannel.ToString(); wrkThread.Start(); } }
//Main class to handle individual channels on separate threads private class LineHandler { public int iChannel = -1; public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread() { try { ADXVoice1 = new ADXVoiceClass(); ADXVoice1.TrunkAssign(iChannel); ADXVoice1.IncomingCall += new _IADXVoiceEvents_IncomingCallEventHandler(OnInco mingCall); } catch (COMException e) { ADXVoice1 = null; return; } catch (Exception e) { ADXVoice1 = null; return; }
//Start message loop (keeps thread from exiting and allows ADX to process events, including state changes) Application.Run();
Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1 eligible for garbage collection GC.Collect(); //force Garbage Collection GC.WaitForPendingFinalizers(); //wait for completion }
private void OnIncomingCall() { //code here to play prompts, branch to other methods, etc. }
} //End LineHandler class
} }
I very much appreciate any advice you may have. Thank you very much.
It looks like you are using an ActiveX Component, now AX was in general not designed to be used from a service, make them work is in general a pain in the a**, the problem is with the callbacks that arrive on anything but the callers thread, that is they end on the thread pool threads which are MTA and as such they need to be marshaled to the STA thread, that means you need to pump Windows messages (not COM message), but services are not designed to pump a message queue, only Windows applications are, you see the dilemma?
I would suggest you to try to run this from a Console application first, it's much easier to debug, and look how far you get before you drop this into a service.
Willy.
Thanks a lot. It is a third party app that should be a .net component... I
make reference to it as a .net component in the .net tab in references.
"Brian Schwartz" <ow***@fishnetcomponentswos.comwrote in message
news:O4**************@TK2MSFTNGP03.phx.gbl...
What does the COM component do? Was it written in-house or is it an
outside product?
If in-house, obviously I'm going to ask if you can rewrite it in .NET. But
since that's probably not the case...what if you wrap the COM component in
a .NET console app, and call the .NET console app from your windows
service? I've never tried it...just an idea off the top of my head.
--
Brian Schwartz
FishNet Components http://www.fishnetcomponents.com
Fish Grid .NET Light: Powerful Layouts for Small Datasets
<msnews.microsoft.comwrote in message
news:e8**************@TK2MSFTNGP06.phx.gbl...
>Thanks Willy. I will try the console approach, however, still need to solve the windows service dilema. For whatever reason the app runs perfectly as a windows form but not as a windows service. And, when I remove application.run from the windows form the app no longer runs. Any idea if there is anything else I can try to get this functioning as a service? Thank you very much. I really appreciate your help. "Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message news:04**********************************@microso ft.com...
>><msnews.microsoft.comwrote in message news:Oi**************@TK2MSFTNGP03.phx.gbl... Thank you. Threading is STA. Here is an excert of the code that works fine as a windows form... But, for some reason I can not put it together to work as a service.
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; using System.Runtime.InteropServices; using Envox.ADXVoice; using System.Data.SqlClient; using System.Configuration;
namespace AnsweringSystem { public partial class Form1 : Form { private LineHandler[] LineArray;
public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { int iFromChannel = 0; int iToChannel = 3; //4 channels
LineArray = new LineHandler[iToChannel - iFromChannel + 1];
for (int iChannel = iFromChannel; iChannel <= iToChannel; iChannel++) { LineHandler Line = new LineHandler(); LineArray[iChannel - iFromChannel] = Line; Line.iChannel = iChannel; ThreadStart ts = new ThreadStart(Line.ProcessingThread); Thread wrkThread = new Thread(ts); Line.CurrentThread = wrkThread; wrkThread.SetApartmentState(ApartmentState.STA); wrkThread.Name = iChannel.ToString(); wrkThread.Start(); } }
//Main class to handle individual channels on separate threads private class LineHandler { public int iChannel = -1; public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread() { try { ADXVoice1 = new ADXVoiceClass(); ADXVoice1.TrunkAssign(iChannel); ADXVoice1.IncomingCall += new _IADXVoiceEvents_IncomingCallEventHandler(OnInc omingCall); } catch (COMException e) { ADXVoice1 = null; return; } catch (Exception e) { ADXVoice1 = null; return; }
//Start message loop (keeps thread from exiting and allows ADX to process events, including state changes) Application.Run();
Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1 eligible for garbage collection GC.Collect(); //force Garbage Collection GC.WaitForPendingFinalizers(); //wait for completion }
private void OnIncomingCall() { //code here to play prompts, branch to other methods, etc. }
} //End LineHandler class
} }
I very much appreciate any advice you may have. Thank you very much. It looks like you are using an ActiveX Component, now AX was in general not designed to be used from a service, make them work is in general a pain in the a**, the problem is with the callbacks that arrive on anything but the callers thread, that is they end on the thread pool threads which are MTA and as such they need to be marshaled to the STA thread, that means you need to pump Windows messages (not COM message), but services are not designed to pump a message queue, only Windows applications are, you see the dilemma?
I would suggest you to try to run this from a Console application first, it's much easier to debug, and look how far you get before you drop this into a service.
Willy.
It's got to be something with the way I'm threading because as soon as I
remove threading and only instantiate one adx object everything works fine.
Aby thoughts?
<msnews.microsoft.comwrote in message
news:Oe**************@TK2MSFTNGP06.phx.gbl...
Thanks a lot. It is a third party app that should be a .net component...
I make reference to it as a .net component in the .net tab in references.
"Brian Schwartz" <ow***@fishnetcomponentswos.comwrote in message
news:O4**************@TK2MSFTNGP03.phx.gbl...
>What does the COM component do? Was it written in-house or is it an outside product?
If in-house, obviously I'm going to ask if you can rewrite it in .NET. But since that's probably not the case...what if you wrap the COM component in a .NET console app, and call the .NET console app from your windows service? I've never tried it...just an idea off the top of my head.
-- Brian Schwartz FishNet Components http://www.fishnetcomponents.com Fish Grid .NET Light: Powerful Layouts for Small Datasets
<msnews.microsoft.comwrote in message news:e8**************@TK2MSFTNGP06.phx.gbl...
>>Thanks Willy. I will try the console approach, however, still need to solve the windows service dilema. For whatever reason the app runs perfectly as a windows form but not as a windows service. And, when I remove application.run from the windows form the app no longer runs. Any idea if there is anything else I can try to get this functioning as a service? Thank you very much. I really appreciate your help. "Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message news:04**********************************@micros oft.com... <msnews.microsoft.comwrote in message news:Oi**************@TK2MSFTNGP03.phx.gbl... Thank you. Threading is STA. Here is an excert of the code that works fine as a windows form... But, for some reason I can not put it together to work as a service. > > using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; using System.Runtime.InteropServices; using Envox.ADXVoice; using System.Data.SqlClient; using System.Configuration; > namespace AnsweringSystem { public partial class Form1 : Form { private LineHandler[] LineArray; > public Form1() { InitializeComponent(); } > private void Form1_Load(object sender, EventArgs e) { int iFromChannel = 0; int iToChannel = 3; //4 channels > LineArray = new LineHandler[iToChannel - iFromChannel + 1]; > for (int iChannel = iFromChannel; iChannel <= iToChannel; iChannel++) { LineHandler Line = new LineHandler(); LineArray[iChannel - iFromChannel] = Line; Line.iChannel = iChannel; ThreadStart ts = new ThreadStart(Line.ProcessingThread); Thread wrkThread = new Thread(ts); Line.CurrentThread = wrkThread; wrkThread.SetApartmentState(ApartmentState.STA); wrkThread.Name = iChannel.ToString(); wrkThread.Start(); } } > //Main class to handle individual channels on separate threads private class LineHandler { public int iChannel = -1; public Thread CurrentThread = null; > private ADXVoiceClass ADXVoice1 = null; > private delegate void TraceThreadSafe(string msg); > public void ProcessingThread() { try { ADXVoice1 = new ADXVoiceClass(); ADXVoice1.TrunkAssign(iChannel); ADXVoice1.IncomingCall += new _IADXVoiceEvents_IncomingCallEventHandler(OnIn comingCall); } catch (COMException e) { ADXVoice1 = null; return; } catch (Exception e) { ADXVoice1 = null; return; } > //Start message loop (keeps thread from exiting and allows ADX to process events, including state changes) Application.Run(); > Marshal.ReleaseComObject(ADXVoice1); //make ADXVoice1 eligible for garbage collection GC.Collect(); //force Garbage Collection GC.WaitForPendingFinalizers(); //wait for completion } > private void OnIncomingCall() { //code here to play prompts, branch to other methods, etc. } > } //End LineHandler class > } } > > I very much appreciate any advice you may have. Thank you very much. >
It looks like you are using an ActiveX Component, now AX was in general not designed to be used from a service, make them work is in general a pain in the a**, the problem is with the callbacks that arrive on anything but the callers thread, that is they end on the thread pool threads which are MTA and as such they need to be marshaled to the STA thread, that means you need to pump Windows messages (not COM message), but services are not designed to pump a message queue, only Windows applications are, you see the dilemma?
I would suggest you to try to run this from a Console application first, it's much easier to debug, and look how far you get before you drop this into a service.
Willy.
<msnews.microsoft.comwrote in message
news:e8**************@TK2MSFTNGP06.phx.gbl...
Thanks Willy. I will try the console approach, however, still need to
solve the windows service dilema. For whatever reason the app runs
perfectly as a windows form but not as a windows service. And, when I
remove application.run from the windows form the app no longer runs. Any
idea if there is anything else I can try to get this functioning as a
service? Thank you very much. I really appreciate your help.
Well, it runs from a Windows.Forms application because this is the normal
habitat for AX controls, they run in an STA thread that pumps the windows
message queue. So, the only way to make it work (be it unreliable) is to
make your service a Windows application, that is, create a context with a
form and run the message pump by a call to Application.Run, but beware that
you need to handle a lot of interactions with the windows system (handle
Windows events like Close etc...), and you'll need to find a way to interact
with the COM object too. Note that such scenario is not supported, it's
really a bad idea to try to run AX in Windows Services, it will break sooner
than later ....
Willy.
<msnews.microsoft.comwrote in message
news:Oe**************@TK2MSFTNGP06.phx.gbl...
Thanks a lot. It is a third party app that should be a .net component...
I make reference to it as a .net component in the .net tab in references.
Wait a minute, if you set a reference to a ".NET component", it means it's a
".NET component" and NOT a COM object, so you may forget all what's been
said about COM, STA's and message queues. So again, may I ask you what you
mean by "it doesn't work", and as I said in another reply, try first to make
it work from a simple Console Application.
Willy.
<msnews.microsoft.comwrote in message
news:%2******************@TK2MSFTNGP02.phx.gbl...
It's got to be something with the way I'm threading because as soon as I
remove threading and only instantiate one adx object everything works
fine. Aby thoughts?
What do you mean by "the way you are threading" and "remove threading"?
Are you sure the third party .NET class doesn't call into COM, that is, are
you sure it's not a simple COM wrapper.
Willy.
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
Create a thread to host your objects (not the main service thread which must
be controlled by the SCM).
In this thread, spend most of your time in a classic
PeekMessage/DispatchMessage loop, so COM marshalling works as expected.
Watching the Output window I'm noticing that without Application.Run in my
windows form app that the message loop doesnt start so the threads exit and
the .net component cant process events. Same thing with the windows
service. All is well in the windows form app with application.run. How can
i simulate this same application.run functionality in a windows service? I
very much appreciate all of your help. Thank you.
"Ben Voigt" <rb*@nospam.nospamwrote in message
news:e9**************@TK2MSFTNGP02.phx.gbl...
>
<msnews.microsoft.comwrote in message
news:Oc*************@TK2MSFTNGP06.phx.gbl...
>>I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). I have created a windows service from VStudio 2005 template. What is the windows service replacement for Application.Run()?
Create a thread to host your objects (not the main service thread which
must be controlled by the SCM).
In this thread, spend most of your time in a classic
PeekMessage/DispatchMessage loop, so COM marshalling works as expected.
<msnews.microsoft.comwrote in message
news:uf**************@TK2MSFTNGP06.phx.gbl...
Watching the Output window I'm noticing that without Application.Run in my
windows form app that the message loop doesnt start so the threads exit
and the .net component cant process events. Same thing with the windows
service. All is well in the windows form app with application.run. How
can i simulate this same application.run functionality in a windows
service? I very much appreciate all of your help. Thank you.
Again, are you talking about a COM object or are you talking about a .NET
component, I'm asking this because in another reply you said that you were
adding a reference to a ".NET component" , and I replied by saying that a
..NET components is not a COM component.
Anyway, if it's a .NET component , it looks like it depends on
Windows.Forms, and this is a big no no in Windows Services, the
documentation states that it's not a supported scenario. If however you
don't care about all these warnings, just go ahaed, make your service a UI
styale application, by adding a reference to Windows.Forms, create a Form as
you did your Windows appliaction and set the Windows Service property
"Interact with the Desktop" to true and set the Identity of the Service
account to SYSTEM. But I warned you, you will end in a world of pain.
Willy.
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:8D**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:uf**************@TK2MSFTNGP06.phx.gbl...
>Watching the Output window I'm noticing that without Application.Run in my windows form app that the message loop doesnt start so the threads exit and the .net component cant process events. Same thing with the windows service. All is well in the windows form app with application.run. How can i simulate this same application.run functionality in a windows service? I very much appreciate all of your help. Thank you.
Again, are you talking about a COM object or are you talking about a .NET
component, I'm asking this because in another reply you said that you were
adding a reference to a ".NET component" , and I replied by saying that a
.NET components is not a COM component.
Anyway, if it's a .NET component , it looks like it depends on
Windows.Forms, and this is a big no no in Windows Services, the
documentation states that it's not a supported scenario. If however you
don't care about all these warnings, just go ahaed, make your service a UI
styale application, by adding a reference to Windows.Forms, create a Form
as you did your Windows appliaction and set the Windows Service property
"Interact with the Desktop" to true and set the Identity of the Service
no, don't enable "Interact with Desktop". That isn't needed for processing
the message queue, and is a very bad idea, not to mention no longer allowed
in Vista.
account to SYSTEM. But I warned you, you will end in a world of pain.
Willy.
"Ben Voigt" <rb*@nospam.nospamwrote in message
news:uv**************@TK2MSFTNGP02.phx.gbl...
>
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:8D**********************************@microsof t.com...
><msnews.microsoft.comwrote in message news:uf**************@TK2MSFTNGP06.phx.gbl...
>>Watching the Output window I'm noticing that without Application.Run in my windows form app that the message loop doesnt start so the threads exit and the .net component cant process events. Same thing with the windows service. All is well in the windows form app with application.run. How can i simulate this same application.run functionality in a windows service? I very much appreciate all of your help. Thank you.
Again, are you talking about a COM object or are you talking about a .NET component, I'm asking this because in another reply you said that you were adding a reference to a ".NET component" , and I replied by saying that a .NET components is not a COM component. Anyway, if it's a .NET component , it looks like it depends on Windows.Forms, and this is a big no no in Windows Services, the documentation states that it's not a supported scenario. If however you don't care about all these warnings, just go ahaed, make your service a UI styale application, by adding a reference to Windows.Forms, create a Form as you did your Windows appliaction and set the Windows Service property "Interact with the Desktop" to true and set the Identity of the Service
no, don't enable "Interact with Desktop". That isn't needed for
processing the message queue, and is a very bad idea, not to mention no
longer allowed in Vista.
>account to SYSTEM. But I warned you, you will end in a world of pain.
Willy.
Agreed, this was only to make it easier for the OP to debug, once he got it
running he could reset this attribute.
It's a very bad idea to have Windows.Forms in Services in the first place,
it's clear that the OP is trying to use a .NET component that has a
dependency on Windows.Forms, (why, is just something the OP is not able to
answer I'm afraid).
It looks like this component needs a Window host (a HWND), maybe it creates
some hidden window or worse has a UI (a tray ICON or whatever), I really
wonder what kind component it is!
Note that you can still interact with the desktop in Vista, be it as an
interim solution for backward compatibility reasons :-(, anyway, Services on
Vista should not run Windows message loops either, everything that needs a
message loop doesn't belong in a Service.
Willy.
Thanks Willy. I have confirmed that it is a .net component. The component
does function when inside a windows service,however, not when multi
threading is involved.
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:8D**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:uf**************@TK2MSFTNGP06.phx.gbl...
>Watching the Output window I'm noticing that without Application.Run in my windows form app that the message loop doesnt start so the threads exit and the .net component cant process events. Same thing with the windows service. All is well in the windows form app with application.run. How can i simulate this same application.run functionality in a windows service? I very much appreciate all of your help. Thank you.
Again, are you talking about a COM object or are you talking about a .NET
component, I'm asking this because in another reply you said that you were
adding a reference to a ".NET component" , and I replied by saying that a
.NET components is not a COM component.
Anyway, if it's a .NET component , it looks like it depends on
Windows.Forms, and this is a big no no in Windows Services, the
documentation states that it's not a supported scenario. If however you
don't care about all these warnings, just go ahaed, make your service a UI
styale application, by adding a reference to Windows.Forms, create a Form
as you did your Windows appliaction and set the Windows Service property
"Interact with the Desktop" to true and set the Identity of the Service
account to SYSTEM. But I warned you, you will end in a world of pain.
Willy.
<msnews.microsoft.comwrote in message
news:Ot****************@TK2MSFTNGP03.phx.gbl...
Thanks Willy. I have confirmed that it is a .net component. The
component does function when inside a windows service,however, not when
multi threading is involved.
Please be more specific,
do you mean it's working from a single thread when running in a Service
process AND this without the need for Windows.Forms?
Is this a pure managed component, or does it have dependencies on other non
managed components like COM?
What kind of component is this and what's his role?
Is this components set documented, what does it say about threading?
What is do you mean with " it's not working when multiple threads are
involved"?
Did you try from a console application and noticed the same behavior? If you
did can you post the console apps. code?
Willy.
Thank you Willy for all of the assistance. I very much appreciate it. I've
been having a hell of a time with this.
Here is Windows Service (no threading) code that does work fine. The Envox
..net component answers OnIncomingCall. Everrything works fine with this
code...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using Envox.ADXVoice;
namespace WindowsService3
{
public partial class Service1 : ServiceBase
{
private ADXVoiceClass ADXVoice1 = null;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(0);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
protected override void OnStop()
{
}
}
}
Here is my multithreaded Windows Service code that does not work
(onincomingcall never executes). I require the 4 threads for the Envox .net
component to listen and answer calls on 4 different lines. This code does
not work for some reason...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Envox.ADXVoice;
namespace WindowsService4
{
public partial class Service1 : ServiceBase
{
private LineHandler[] LineArray;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
StartApp();
}
private void StartApp()
{
int iFromTrunk = 0;
int iToTrunk = 14;
LineArray = new LineHandler[iToTrunk - iFromTrunk + 1];
for (int iTrunk = iFromTrunk; iTrunk <= iToTrunk; iTrunk++)
{
LineHandler Line = new LineHandler();
LineArray[iTrunk - iFromTrunk] = Line;
Line.iTrunk = iTrunk;
ThreadStart ts = new ThreadStart(Line.ProcessingThread);
Thread wrkThread = new Thread(ts);
Line.CurrentThread = wrkThread;
wrkThread.SetApartmentState(ApartmentState.STA); //default is
MTA
wrkThread.Name = iTrunk.ToString();
wrkThread.Start();
}
}
protected override void OnStop()
{
}
private class LineHandler
{
public int iTrunk = -1;
public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread()
{
int iThreadId = CurrentThread.GetHashCode();
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iTrunk);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
//Start message loop (keeps thread from exiting and allows
Envox .net component to process events, including state changes)
//Windows service aternate to application.run required
here...
//Application.Run();
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
}
}
}
The above code, however, does function as a windows form whe using
paplication.run. I'd very much appreciate you comments or advice. Thank
you very much.
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:5E**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:Ot****************@TK2MSFTNGP03.phx.gbl...
>Thanks Willy. I have confirmed that it is a .net component. The component does function when inside a windows service,however, not when multi threading is involved.
Please be more specific,
do you mean it's working from a single thread when running in a Service
process AND this without the need for Windows.Forms?
Is this a pure managed component, or does it have dependencies on other
non managed components like COM?
What kind of component is this and what's his role?
Is this components set documented, what does it say about threading?
What is do you mean with " it's not working when multiple threads are
involved"?
Did you try from a console application and noticed the same behavior? If
you did can you post the console apps. code?
Willy.
<msnews.microsoft.comwrote in message
news:Os**************@TK2MSFTNGP03.phx.gbl...
Thank you Willy for all of the assistance. I very much appreciate it.
I've been having a hell of a time with this.
Here is Windows Service (no threading) code that does work fine. The
Envox .net component answers OnIncomingCall. Everrything works fine with
this code...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using Envox.ADXVoice;
namespace WindowsService3
{
public partial class Service1 : ServiceBase
{
private ADXVoiceClass ADXVoice1 = null;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(0);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
protected override void OnStop()
{
}
}
}
Here is my multithreaded Windows Service code that does not work
(onincomingcall never executes). I require the 4 threads for the Envox
.net component to listen and answer calls on 4 different lines. This code
does not work for some reason...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Envox.ADXVoice;
namespace WindowsService4
{
public partial class Service1 : ServiceBase
{
private LineHandler[] LineArray;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
StartApp();
}
private void StartApp()
{
int iFromTrunk = 0;
int iToTrunk = 14;
LineArray = new LineHandler[iToTrunk - iFromTrunk + 1];
for (int iTrunk = iFromTrunk; iTrunk <= iToTrunk; iTrunk++)
{
LineHandler Line = new LineHandler();
LineArray[iTrunk - iFromTrunk] = Line;
Line.iTrunk = iTrunk;
ThreadStart ts = new ThreadStart(Line.ProcessingThread);
Thread wrkThread = new Thread(ts);
Line.CurrentThread = wrkThread;
wrkThread.SetApartmentState(ApartmentState.STA); //default
is MTA
wrkThread.Name = iTrunk.ToString();
wrkThread.Start();
}
}
protected override void OnStop()
{
}
private class LineHandler
{
public int iTrunk = -1;
public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread()
{
int iThreadId = CurrentThread.GetHashCode();
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iTrunk);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
//Start message loop (keeps thread from exiting and allows
Envox .net component to process events, including state changes)
//Windows service aternate to application.run required
here...
//Application.Run();
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
}
}
}
The above code, however, does function as a windows form whe using
paplication.run. I'd very much appreciate you comments or advice. Thank
you very much.
Sorry ,but I can't help you out if you don't answer my questions (see my
previous reply), also I didn't ask to post the service code, I asked for a
Console application. Anyway, as I said before, I'm pretty sure this .NET
component (if it's really not a AX Control) is hiding an unmanaged component
(guess, a COM ActiveX control from Envox), so again check this! Ask the
implementer of the .NET component, if you are not able to find this out
yourself. I can't possibly know what the NET wrapper (if any) is doing at
the thread level, whether it creates forms or not, the same is true for the
underlying control. All I can say is that if it's an AX control, forget it
to make it work from a Service, If you don't believe me , ask Envox whether
they support this to be run in a Windows Service, the answer will be NO.
One last question though, why do you want it to be run from a Service, why
can't you run it from a Windows application?
Willy.
<msnews.microsoft.comwrote in message
news:Os**************@TK2MSFTNGP03.phx.gbl...
Thank you Willy for all of the assistance. I very much appreciate it.
I've been having a hell of a time with this.
Here is Windows Service (no threading) code that does work fine. The
Envox .net component answers OnIncomingCall. Everrything works fine with
this code...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using Envox.ADXVoice;
namespace WindowsService3
{
public partial class Service1 : ServiceBase
{
private ADXVoiceClass ADXVoice1 = null;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(0);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
protected override void OnStop()
{
}
}
}
Here is my multithreaded Windows Service code that does not work
(onincomingcall never executes). I require the 4 threads for the Envox
.net component to listen and answer calls on 4 different lines. This code
does not work for some reason...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Envox.ADXVoice;
namespace WindowsService4
{
public partial class Service1 : ServiceBase
{
private LineHandler[] LineArray;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
StartApp();
}
private void StartApp()
{
int iFromTrunk = 0;
int iToTrunk = 14;
LineArray = new LineHandler[iToTrunk - iFromTrunk + 1];
for (int iTrunk = iFromTrunk; iTrunk <= iToTrunk; iTrunk++)
{
LineHandler Line = new LineHandler();
LineArray[iTrunk - iFromTrunk] = Line;
Line.iTrunk = iTrunk;
ThreadStart ts = new ThreadStart(Line.ProcessingThread);
Thread wrkThread = new Thread(ts);
Line.CurrentThread = wrkThread;
wrkThread.SetApartmentState(ApartmentState.STA); //default
is MTA
wrkThread.Name = iTrunk.ToString();
wrkThread.Start();
}
}
protected override void OnStop()
{
}
private class LineHandler
{
public int iTrunk = -1;
public Thread CurrentThread = null;
private ADXVoiceClass ADXVoice1 = null;
private delegate void TraceThreadSafe(string msg);
public void ProcessingThread()
{
int iThreadId = CurrentThread.GetHashCode();
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iTrunk);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
//Start message loop (keeps thread from exiting and allows
Envox .net component to process events, including state changes)
//Windows service aternate to application.run required
here...
//Application.Run();
}
private void OnIncomingCall()
{
try
{
ADXVoice1.ClearDigits();
ADXVoice1.AnswerCall();
Play_Welcome_Message();
}
finally
{
if (ADXVoice1.TrunkState != DEV_STATE.DEV_STATE_Idle)
{
ADXVoice1.DisconnectCall();
}
}
}
private void Play_Welcome_Message()
{
ADXVoice1.PlayFile(@"e:\voxfiles\144.vox", null, "+", null,
null);
ADXVoice1.PlayFile(@"e:\voxfiles\145.vox", null, "+", null,
null);
}
}
}
}
The above code, however, does function as a windows form whe using
paplication.run. I'd very much appreciate you comments or advice. Thank
you very much.
I took a quick look at your code (the second case), and found that you don't
keep your threads running at all, all you are doing is create an instance of
ADXVoiceClass add an eventhandler and return from your thread procedure,
that means that the thread will most probably get collected at the next GC
run. That means that basically you don't have any of your 15 threads running
( that is pumping messages). At least you need to keep the thread running
and pump the queue (again STA threads need to pump the queue!!), for COM
messages only, you can do this by means of a pumping wait like :
public void ProcessingThread()
{
....
// pump COM messages once per second, in an endless loop!!
while(!Thread.CurrentThread.Join(new TimeSpan(0,0,1)));
}
for Windows messages you need Application.Run().
Willy.
<msnews.microsoft.comwrote in message
news:Os**************@TK2MSFTNGP03.phx.gbl...
ADXVoice1 = new ADXVoiceClass();
ADXVoice1.TrunkAssign(iTrunk);
ADXVoice1.IncomingCall += new
_IADXVoiceEvents_IncomingCallEventHandler(OnIncomi ngCall);
Oh, this ....
_IADXVoiceEvents
confirms what I've said before, the component is most certainly an ActiveX
control NOT a .NET component, the IADXVoiceEvents denotes COM
ConnectionPoint interface (probably a Windowless ATL Control interface) .
Following summarizes what you need to take care of when hosting such
control:
First, AX Controls are "Apartment" threaded, so you better initialize your
threads to enter an STA, else your objects will end on the default STA
thread created by COM.
Second, STA threads should to pump the message queue (COM message only),
this is required by the Finalizer thread, who runs in the MTA, to be able to
release the RCW when you're done with the object.
It's however not required by COM interop, as long as you don't need to
marshal across incomaptible apartments, and here you don't.
What you have to do is keep your threads pumping COM messages, this can be
achieved by calling a pumping wait.
For instance you could have a loop that calls Thread.Join with a timeout, or
better a Wait on an event with a timeout, this way you can do stuff like
detach your eventhandlers release the COM objects and stop your threads in
your service OnStop handler.
Following snippet, illustrates most of this, (not tested!)...
const int threads = 15;
ManualResetEvent[] mre = new ManualResetEvent[threads];
....
Thread[] t = new Thread[threads];
for (int i = 0; i < threads; i++)
{
signals[i] = new ManualResetEvent(false);
t[i] = new Thread(new
ParameterizedThreadStart(ProcessingThread),200000) ;
t[i].SetApartmentState(ApartmentState.STA);
t[i].IsBackground=true;
t[i].Start(mre[i]);
}
public void ProcessingThread(object shutdownEvent)
{
....
ADXVoice1.InCommingCall += new
_IADXVoiceEvents_InCommingCallEventHandler(OnIncom ingCall);
// Wait 100 msec. for event to be set, leave the loop when set,
WaitOne pumps COM messages
while (!((ManualResetEvent)(shutdownEvent)).WaitOne(100, true))
;
// signaled to stop, detach handler and release COM object
ADXVoice1.InCommingCall -= new
_IADXVoiceEvents_InCommingCallEventHandler(OnIncom ingCall);
Marshal.ReleaseComObject(ADXVoice1);
}
...
protected override void OnStop()
{
for (int n = 0; n < threads; n++)
mre[n].Set();
// Wait for threads to end.... use Join or whatever other
synchronization primitive,
// keeping in mind that you need to return from OnStop before the
SCM gets nervous
}
Willy.
Thank you very much, Willy. I really appreciate all of the help. I have
tried these and other methods to get this windows service functioning,
however, I've been unsuccessful. I think I'm going to have to assume that
this component just doesn't function as a multithreaded windows service.
Without threading I can the windows service to run properly so perhaps I can
just create 15 windows services (not perfered). I require this application
to run continually so windows service is the way to go. Alternatively I may
just have to have the multithreaded windows form app running in a terminal
service session (again not perfered). Anyways, I really appreciate all of
your help. Thank you very much.
Jay
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:CF**********************************@microsof t.com...
<msnews.microsoft.comwrote in message
news:Os**************@TK2MSFTNGP03.phx.gbl...
> ADXVoice1 = new ADXVoiceClass(); ADXVoice1.TrunkAssign(iTrunk); ADXVoice1.IncomingCall += new _IADXVoiceEvents_IncomingCallEventHandler(OnIncom ingCall);
Oh, this ....
_IADXVoiceEvents
confirms what I've said before, the component is most certainly an ActiveX
control NOT a .NET component, the IADXVoiceEvents denotes COM
ConnectionPoint interface (probably a Windowless ATL Control interface) .
Following summarizes what you need to take care of when hosting such
control:
First, AX Controls are "Apartment" threaded, so you better initialize your
threads to enter an STA, else your objects will end on the default STA
thread created by COM.
Second, STA threads should to pump the message queue (COM message only),
this is required by the Finalizer thread, who runs in the MTA, to be able
to release the RCW when you're done with the object.
It's however not required by COM interop, as long as you don't need to
marshal across incomaptible apartments, and here you don't.
What you have to do is keep your threads pumping COM messages, this can be
achieved by calling a pumping wait.
For instance you could have a loop that calls Thread.Join with a timeout,
or better a Wait on an event with a timeout, this way you can do stuff
like detach your eventhandlers release the COM objects and stop your
threads in your service OnStop handler.
Following snippet, illustrates most of this, (not tested!)...
const int threads = 15;
ManualResetEvent[] mre = new ManualResetEvent[threads];
...
Thread[] t = new Thread[threads];
for (int i = 0; i < threads; i++)
{
signals[i] = new ManualResetEvent(false);
t[i] = new Thread(new
ParameterizedThreadStart(ProcessingThread),200000) ;
t[i].SetApartmentState(ApartmentState.STA);
t[i].IsBackground=true;
t[i].Start(mre[i]);
}
public void ProcessingThread(object shutdownEvent)
{
....
ADXVoice1.InCommingCall += new
_IADXVoiceEvents_InCommingCallEventHandler(OnIncom ingCall);
// Wait 100 msec. for event to be set, leave the loop when set,
WaitOne pumps COM messages
while (!((ManualResetEvent)(shutdownEvent)).WaitOne(100, true))
;
// signaled to stop, detach handler and release COM object
ADXVoice1.InCommingCall -= new
_IADXVoiceEvents_InCommingCallEventHandler(OnIncom ingCall);
Marshal.ReleaseComObject(ADXVoice1);
}
...
protected override void OnStop()
{
for (int n = 0; n < threads; n++)
mre[n].Set();
// Wait for threads to end.... use Join or whatever other
synchronization primitive,
// keeping in mind that you need to return from OnStop before
the SCM gets nervous
}
Willy.
<msnews.microsoft.comwrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
Thank you very much, Willy. I really appreciate all of the help. I have
tried these and other methods to get this windows service functioning,
however, I've been unsuccessful. I think I'm going to have to assume that
this component just doesn't function as a multithreaded windows service.
Without threading I can the windows service to run properly so perhaps I
can just create 15 windows services (not perfered). I require this
application to run continually so windows service is the way to go.
Alternatively I may just have to have the multithreaded windows form app
running in a terminal service session (again not perfered). Anyways, I
really appreciate all of your help. Thank you very much.
Weird, If it works in a Forms application using multiple threads, it should
also work from a service, provided things are initialized correctly.
I would try to make it run from a console application, if this works, you
can schedule this application to start at boot time using the system
scheduler.
Willy. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Michael |
last post by:
Hi,
I have a windows service developed using c# and it needs to lunch another
windows application. I have been trying to use Process class to do it but the
problem is becase windows service...
|
by: CodeMonkey |
last post by:
Hi,
I was wondering if anybody could give me some advice on how to
structure an application that I am about to start work on.
The vague requirements will be:
1) Always-On monitoring of data...
|
by: nkunapa |
last post by:
Hi:
I am looking for any ideas/comments/suggestions on how a Windows
Service kind of functionality can be acheived from a web application
which which will run under IIS or for that matter any...
|
by: kumar_anil_gaya_India |
last post by:
Hi All,
I am facing one problem. I have one DLL called LogManagement which has
ability to write to ExceptionLog and EventLog File. Both are separate file
locate in Logs Diectory. I have two ...
|
by: Todd Jaspers |
last post by:
Hey guys,
I've written a fairly simple Windows C# Application using Visual Studio
2005. I have to manually run it, but I would prefer to have it run on it's
own, as if it was a Windows NT...
|
by: illegal.prime |
last post by:
Hi all, I have a service that needs to start a regular windows
application.
I'm running the service as ServiceAccount.LocalSystem.
But, when it starts the process (using Process.Start) the GUI...
|
by: Jake K |
last post by:
I have a multithreaded application that I now want to convert into a Windows
Service. Does application.run work in a windows service? Are there things
to take into consideration when creating a...
|
by: =?Utf-8?B?dmlzaHJ1dGg=?= |
last post by:
Hi,
I have 2 applications running, one Windows application project and the other
windows services project.
I want to call my Windows application in my windows services.
I want to run them as...
|
by: =?Utf-8?B?dmlzaHJ1dGg=?= |
last post by:
Hi,
I have 2 applications running, one Windows application project and the other
windows services project.
I want to call my Windows application in my windows services.
I want to run them as...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: jack2019x |
last post by:
hello, Is there code or static lib for hook swapchain present?
I wanna hook dxgi swapchain present for dx11 and dx9.
| |