none
Windows service with two timers but an event is never execute. RRS feed

  • Question

  • Hi, I have a Windows Service with two timers. In the OnStart method:

    checkTimer1.Elapsed += new ElapsedEventHandler(OnCheckTimer1Time);
    checkTimer1.Interval = 300000; //5 min
    checkTimer1.Enabled = true;
    
    checkTimer2.Elapsed += new ElapsedEventHandler(OnCheckTimer2Time);
    checkTimer2.Interval = 600000; //10 min
    checkTimer2.Enabled = true;


    OnCheckTimer1Time:

    private void OnCheckTimer1Time(object source, ElapsedEventArgs e)
    {
     writeLog("something timer 1");
    }


    OnCheckTimer2Time:

    private void OnCheckTimer2Time(object source, ElapsedEventArgs e)
    {
     writeLog("something timer 2");
    }

    and writeLog:

    try
    {
      using (StreamWriter sw = new StreamWriter(@"C:\Users\myuser\Desktop\logFile.txt", true))
           sw.WriteLine(line);
     }
    catch (Exception)
     {
        return;
     }

    But the "something timer 2" is never printed on file. I think that this is because 600000 is a multiple of 300000 and when it's the time in which the two event must be called, only the first event is executed. 

    Can someone tell me why I have this behavior and how I can solve that, protecting my file from the cuncurrent access?

    The two timer are of System.Timers components

    PS: if I choose 30000 ms e 600121 ms in the timer Interval, in my file I have both the something timer 1 and something timer 2 strings. 








    Tuesday, February 4, 2020 10:36 AM

Answers

  • The problem is that events can try to write to file at the same time so you need to synchronize file write somehow. Quick example to test is create static object instance to lock while writing to file. Better solution might be dedicated class that writes log and makes sure only one thread can write file.

    // As class field.
    private static readonly object logFileLock = new object();
    
    try
    {
      lock (logFileLock)
      {
        using (StreamWriter sw = new StreamWriter(@"C:\Users\myuser\Desktop\logFile.txt", true))
             sw.WriteLine(line);
      }
     }
    catch (Exception)
     {
        return;
     }

    Tuesday, February 4, 2020 1:38 PM

All replies

  • Have you tried using EventLog.WriteEntry to determine if code is being executed properly? Another option is to lower the time on the Timers and use Debugger.Launch (see code sample) to step through the code to see if the code is executing.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, February 4, 2020 11:05 AM
    Moderator
  • Have you tried using EventLog.WriteEntry to determine if code is being executed properly? Another option is to lower the time on the Timers and use Debugger.Launch (see code sample) to step through the code to see if the code is executing.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    I'm sure that the problem is that the file is shared between the two events. Infact, when 10 minutes have elapsed, the event1 is execute and the event2 is executed too. How I can protect my file against the cuncurrent access?
    Tuesday, February 4, 2020 11:16 AM
  • One thing I missed in your code is your catch never does anything except ignore any errors which means it mask any errors. You need to either handle errors or record them e.g. as I mention write to the event log.

    To prevent concurrent access, use a Singleton as a last resort where the code in the singleton class controls all operations from opening the file, writing and closing/saving the file. I don't have an example for this specific operation but the following show how to write a singleton which control access to a incrementing string which I use in a Windows service. 

    Using a singleton would be a last resort, personally I would want to know if an exception is being thrown by writing to the event log in place of your return statement in the catch.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, February 4, 2020 11:37 AM
    Moderator
  • The problem is that events can try to write to file at the same time so you need to synchronize file write somehow. Quick example to test is create static object instance to lock while writing to file. Better solution might be dedicated class that writes log and makes sure only one thread can write file.

    // As class field.
    private static readonly object logFileLock = new object();
    
    try
    {
      lock (logFileLock)
      {
        using (StreamWriter sw = new StreamWriter(@"C:\Users\myuser\Desktop\logFile.txt", true))
             sw.WriteLine(line);
      }
     }
    catch (Exception)
     {
        return;
     }

    Tuesday, February 4, 2020 1:38 PM
  • The problem is that events can try to write to file at the same time so you need to synchronize file write somehow. Quick example to test is create static object instance to lock while writing to file. Better solution might be dedicated class that writes log and makes sure only one thread can write file.

    // As class field.
    private static readonly object logFileLock = new object();
    
    try
    {
      lock (logFileLock)
      {
        using (StreamWriter sw = new StreamWriter(@"C:\Users\myuser\Desktop\logFile.txt", true))
             sw.WriteLine(line);
      }
     }
    catch (Exception)
     {
        return;
     }

    Thank you a lot
    Tuesday, February 4, 2020 1:46 PM