I developed Windows service that is using System.Threading.Timer. Timer is starting every x minutes and it works fine (timer is updatet at the end of method). But, if there is an error in try block service just stops despite the fact that I'm updating timer and telling him when to start again
why is that happening? Here is code :
System.Threading.Timer serviceTimer;
protected override void OnStart(string[] args)
{
TimeSpan diff;
diff = nextRun - now;
TimerCallback timerDelegate =
new TimerCallback(MyTimerCallback);
serviceTimer = new System.Threading.Timer(timerDelegate, null,
diff, new TimeSpan(-1));
}
public void MyTimerCallback(object something)
{
try
{
//possible error that happened
}
catch(Exception)
{
}
finally
{
//diff is a new variable telling timer when to start again
serviceTimer.Change(diff, new TimeSpan(-1));
}
}
what am I missing why service stops if there was an error?
Maybe the timer wasn't able to change. Timer.Change returns a boolean:
true if the timer was successfully updated; otherwise, false.
But you're not checking that result. I'd recommend probably disposing the timer and newing up a new one each time, since it's already fired and you created it as a "one shot" timer, e.g.
finally
{
serviceTimer.Dispose();
serviceTimer = new System.Threading.Timer(timerDelegate, null,
diff, new TimeSpan(-1));
}
In case that someone deals with same problem I figured something like this:
Since I want my service to stay alive no matter what :
I 'm reporting to the service manager that the service has successfully started -
base.OnStart(args);
In configuration you can set legacyUnhandledExceptionPolicy set to true (1)
Related
I have a large proces that I need to debug and the proces could stop at anytime. I have configured Visual Studio 2017, to stop at any thrown exception, as in, even if it is handled, because I want to see what caused the exception. What I need is some sort of alarm when this happens, so that I can leave the program to run and then alert me if anything comes up. The only thing I have found is an alarm sound when a break point is hit, but it might not be a break point and I need more than a sound, I need to be able to execute some code, so that I can make my Phone go nuts or whatever. Is there any way I can trigger code when the debugger enters break mode?
Thanks in advance.
It is, using a VS package. You'll need to add this attribute on top of the class in order for code to run on package startup:
[ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] ///Able to run code on solution startup
Add these class values variables:
private DTE2 applicationObject;
private BuildEvents buildEvents;
private DebuggerEvents debugEvents;
then the following code can run:
protected override void Initialize()
{
base.Initialize();
applicationObject = (DTE2)GetService(typeof(DTE));
buildEvents = applicationObject.Events.BuildEvents;
debugEvents = applicationObject.Events.DebuggerEvents;
SetupEventHandlers();
}
And finally the code we have "all" being waiting for:
private void SetupEventHandlers()
{
//buildEvents.OnBuildDone += (scope, action) =>
//{
//};
debugEvents.OnEnterBreakMode += delegate (dbgEventReason reason, ref dbgExecutionAction action)
{
};
//var componentModel =
// GetGlobalService(typeof(SComponentModel)) as IComponentModel;
//if (componentModel == null)
//{
// Debug.WriteLine("componentModel is null");
// return;
//}
//var operationState = componentModel.GetService<IOperationState>();
//operationState.StateChanged += OperationStateOnStateChanged;
}
We have a process that is executed as a windows service,
This process serves as an interface server processing incoming messages, transforms them and sends them out to another interface.
it is a rather heavy process, it needs to load a lot of things into memory and that takes some time (few minutes).
due to its nature, when we start it using its windows service, it remains in "starting" status for a very long time (sometimes more than 20 minutes)
even when we can see the process already works and process messages just fine (going by its logs).
so the question is - when is a service considered "starting" and when is it considered "started"? based on what factors?
Starting status finish when onstart is completed.
You should write starting code after onstart event.
puclic class Service1
{
private Timer timer = new Timer();
protected override void OnStart(string[] args)
{
this.timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
this.timer.Interval = 1 * 1000; // 1 second
this.timer.Enabled = true;
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
this.timer.Enabled = false; // OnElapsedTime run only one time
// Write your code
}
}
I am doing a windows service (call it SampleService), every is fine. When I started then stopped service through Windows Service Management Tool (service.msc), it run properly.
But my service will be request Start and Stop by another application. So I will not use Windows Service Management Tool in this case.
This is my service implement.
using System.ServiceProcess;
public partial class SampleService : ServiceBase
{
public SampleService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.WriteLog("OnStart");
// Doing start service logic down here
// Some service logic like create some files.
// Or just leave it empty like a brand new Windows Service.
}
protected override void OnStop()
{
this.WriteLog("OnStop");
// Doing clean service logic down here.
// Some service logic like: delete files.
// Or just leave it empty like a brand new Windows Service.
}
static readonly object synObject = new object();
public void WriteLog(string message)
{
if (string.IsNullOrEmpty(message))
{
return;
}
// Write log.
lock (synObject)
{
using (var wr = new StreamWriter(#"C:\logfile.txt", true))
{
wr.WriteLine(DateTime.Now + "-" + message);
}
}
}
}
And this is code logic use to Start and Stop service inside my another application. I can not modify this another application. The bellow source code simulate what happen.
class Program
{
static void Main(string[] args)
{
ServiceController sc = new ServiceController("SampleService");
// start service
sc.Start();
// doing some logic cost deltaTime or just stand by in deltaTime.
Thread.Sleep(deltaTime);
try
{
// stop service first time, nothing happen.
sc.Stop();
}
catch
{
}
try
{
// stop service second times, by dump people or apllication.
sc.Stop();
}
catch
{
// It got an exception here: "The service cannot accept control messages at this time".
// But the service did stopped.
}
}
}
The problem is:"When deltaTime is too short (bellow 3000ms with empty OnStart(), OnStop()), Service will stop incorrectly. The output log OnStop will never show up, that mean OnStop method did not called.
My service will doing clean up work in OnStop (like delete some file), but if it not be called, these files still there.
I cannot change logic of another application but I can change SampleService.
I want to ask:
Is this an Windows Service base issue and I cant do anything with it?
What ever it is, can I do clean up some where else?
Thank you!
I am using JNA to access User32 functions (I dont think it has got to do with Java here, more of concept problem). In my application, I have a Java process which communicates with the Canon SDK. To dispatch any messages I am using the below function:
private void peekMessage(WinUser.MSG msg) throws InterruptedException {
int hasMessage = lib.GetMessage(msg, null, 0, 0);
if (hasMessage != 0) {
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
Thread.sleep(1);
}
peekMessage is called in a loop and it all works well. Whenever an Image is taken from camera, I get the event and do the rest.
But I have observed, say after about 15 seconds (sometimes never or sometimes just at start) of no activity with camera, taking picture does not give me any download event. Later the whole application becomes unusable as it doesn't get any events from camera.
What can be the reason for this? Please let me know of any other info needed, I can paste the respective code along.
Edit:
Initialization:
Map<String, Integer> options = new HashMap<String, Integer>();
lib = User32.INSTANCE;
hMod = Kernel32.INSTANCE.GetModuleHandle("");
options.put(Library.OPTION_CALLING_CONVENTION, StdCallLibrary.STDCALL_CONVENTION);
this.EDSDK = (EdSdkLibrary) Native.loadLibrary("EDSDK/dll/EDSDK.dll", EdSdkLibrary.class, options);
private void runNow() throws InterruptedException {
while (!Thread.currentThread().isInterrupted()) {
Task task = queue.poll();
if (task != null) {
int taskResult = task.call();
switch (taskResult) {
case (Task.INITIALIZE_STATE):
break;
case (Task.PROCESS_STATE):
break;
case (Task.TERMINATE_STATE): {
//queue.add(new InitializeTask());
Thread.currentThread().interrupt();
break;
}
default:
;
}
}
getOSEvents();
}
}
WinUser.MSG msg = new WinUser.MSG();
private void getOSEvents() throws InterruptedException {
if (isMac) {
receiveEvents();
} else {
peekMessage(msg);
}
}
Above, whenever I get my camera event, it add's it to the queue and in each loop I check the queue to process any Task. One more important information: This is a process running on cmd and has no window. I just need the events from my camera and nothing else.
The code where I register callback functions:
/**
* Adds handlers.
*/
private void addHandlers() {
EdSdkLibrary.EdsVoid context = new EdSdkLibrary.EdsVoid(new Pointer(0));
int result = EDSDK.EdsSetObjectEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsObjectEvent_All), new ObjectEventHandler(), context).intValue();
//above ObjectEventHandler contains a function "apply" which is set as callback function
context = new EdSdkLibrary.EdsVoid(new Pointer(0));
result = EDSDK.EdsSetCameraStateEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsStateEvent_All), new StateEventHandler(), context).intValue();
//above StateEventHandler contains a function "apply" which is set as callback function
context = new EdSdkLibrary.EdsVoid(new Pointer(0));
result = EDSDK.EdsSetPropertyEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsStateEvent_All), new PropertyEventHandler(), context).intValue();
//above PropertyEventHandler contains a function "apply" which is set as callback function
}
You are getting ALL messages from ALL windows that belong to this thread, that includes all mouse moves, paints etc. if you aren't rapidly calling this function your message queue will overflow and cause the behavior you describe.
The sleep you definitely don't want as GetMessage yields if no message is waiting.
So if there exists a normal message pump(s) (i.e GetMessage/DispatchMessage) loop somewhere else for this threads window(s) then you should let that pump do most of the work, perhaps use wMsgFilterMin, wMsgFilterMax to just get the event message you require; or even better in this case use peekmessage with PM_NOREMOVE (then you will need your sleep
call as peekmessage returns immediately).
Alternatively provide the hWnd of the window that generates the event to reduce the workload.
Use spy++ to look into which windows this thread owns and what messages are being produced.
To take this answer further please provide answers to: what else is this thread doing and what windows does it own; also is this message pump the only one or do you call into the SDK API where it may be pumping messages too?
There is an OpenSource project wrapping EDSDK with JNA and it has a version of your code that is probably working better:
https://github.com/kritzikratzi/edsdk4j/blob/master/src/edsdk/api/CanonCamera.java#L436
Unfortunately this is not platform independent and specifically the way things work on windows. I am currently in the process of trying to get a MacOS version of things working at:
https://github.com/WolfgangFahl/edsdk4j
in the ServiceStart() call of a windows service, I create a thread and start it.
Thread1 = New TThread1(false)
In the Execute procedure of the subthread, there is a loop that runs forever and does that the service is supposed to do.
The problem is that when I get an error in this thread, I want to terminate the thread, and stop the service too.
How can I get the service to stop itself if a thread that it has started stops (fails).
A possibility is to use watchdog timers:
in your thread you reset the timer (eg. every time you enter the loop).
when interval of timer is expired, you know that the thread is probably not working anymore, so you can restart the service or what ever...
A better approach might be to catch exceptions in the thread and log them. Or you could catch the exception, log it, then stop the service. That way you are in control of the service stopping and you also have some insight into the errors being generated.
make a call to stop service :
bool StopService(string svr_name)
{
bool ret = false;
if (svr_name.Length > 0)
{
try
{
ServiceController sc = new ServiceController(svr_name);
if (sc.Status == ServiceControllerStatus.Stopped)
{
return true;
}
sc.Stop();
}
catch (Exception)
{
return false;
}
}
return ret;
}