service - Timer and Processing Issues in C# -


i have service processes files. process , take long time. can't control process sends files me. randomly dropped on me throughout day , night. when use timer, seems "processfiles" method abandoned whereever when time has elapsed , processfiles called again. since files contain sensitive information, can't sit on server long time can't set timer longer 5 minutes and, still, @ 5 minutes, process interrupts itself. result, have partially processed files. appreciate thoughts , input on quandary.

    system.timers.timer _timer;      // files come in, massage them , encrypt them      public const string inpath = @"c:\input";     public const string outpath = @"\c:\output";      public filemassaging()     {         initializecomponent();     }      public eventlog myeventlog = new eventlog();     public string ssource = "filemassaging";     public string slog = "filemassaging";      protected override void onstart(string[] args)     {         // create source, if not exist.         if (!eventlog.sourceexists(ssource))             eventlog.createeventsource(ssource, slog);          // set service         servicestatus servicestatus = new servicestatus();         servicestatus.dwcurrentstate = servicestate.service_start_pending;         servicestatus.dwwaithint = 100000;         setservicestatus(this.servicehandle, ref servicestatus);          // set service          _timer = new system.timers.timer();         _timer.elapsed += new system.timers.elapsedeventhandler(this.ontimer);         _timer.interval = 5000;         _timer.start();           // update service state running.         servicestatus.dwcurrentstate = servicestate.service_running;         setservicestatus(this.servicehandle, ref servicestatus);     }       public void ontimer(object sender, system.timers.elapsedeventargs args)     {         processfiles();     }         public void processfiles()     {             string[] originalfiles = directory.getfiles(inpath + @"\", "*.txt");             foreach (string filename in originalfiles)             {                  // check , process file                  checkfile(inpath, outpath, filename);             }       }      public void checkfile(string inpath,outpath, filename)        {        // example -- actual file processing longer        //         string infile = inpath+filename;        string outfile= outpath+filename;        file.move(infile,outfile,true);       } 

for testing , extensiblity recommend different overall structure.

first let's seperate out work classes makes sense. lets start class called folderwatcher:

public class folderwatcher     {         private readonly string _inpath;         private readonly string _outpath;          public bool currentlyrunning { get; set; }          public folderwatcher(string inpath, string outpath)         {             _inpath = inpath;             _outpath = outpath;         }          public void tryprocessfiles(object sender, elapsedeventargs e)         {             try             {                 this.currentlyrunning = true;                 processfiles(sender, e);             }             catch (exception)             {                 throw;             }                         {                 this.currentlyrunning = false;             }         }          public void processfiles(object sender, elapsedeventargs e)         {              string[] originalfiles = getfilesindirectory();             foreach (var originalfile in originalfiles)             {                 checkfile(originalfile);             }         }          // internal/virtual can mocked in unit testing.         internal virtual string[] getfilesindirectory()         {             return directory.getfiles(_inpath + @"\", "*.txt");         }          // internal/virtual can mocked in unit testing.         internal virtual void checkfile(string filename)         {             string infile = $"{_inpath}{filename}";             string outfile = $"{_outpath}{filename}";             file.move(infile, outfile);         }      } 

this class has single responsibility, move files in response event.

next let's build class wrap folderwatcher class handles timer functionality:

    public class timedfolderwatcher     {         private readonly folderwatcher _folderwatcher;         private readonly timer _timer;          public timedfolderwatcher(folderwatcher folderwatcher)         {             _folderwatcher = folderwatcher;             inittimer();         }          private void inittimer()         {             _timer.elapsed += new system.timers.elapsedeventhandler(this.processfiles);             _timer.interval = 5000;             _timer.start();         }          private void processfiles(object sender, elapsedeventargs e)         {             _folderwatcher.tryprocessfiles(sender, e);         }     } 

this class has single responsibility call processfiles method every 5000 milliseconds.

lastly can init , call these classes way:

var filemassageservice = new timedfolderwatcher(new folderwatcher(@"c:\input", @"c:\output")); 

this approach lends testing , follows best practices of dependency injection allow use ioc framework in future if need to.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -