Note that there are some explanatory texts on larger screens.

plurals
  1. POproper way to handle windows service error
    primarykey
    data
    text
    <p>I'm building a multi-thread windows service. I'm having a little difficulty figuring out the best way to cleanly stop the service once all the threads have run through. The code is below. I have looked at ManualResetEvent, CountdownEvent and using Interlocked. I'm not sure which one would best suit my implementation.</p> <p>Thanks for the assistance.</p> <pre><code> private bool _isExiting; private bool IsExiting //if this is set to true exit but wait for all threads { get { return _isExiting; } set { _isExiting = value; if (value) Stop(); } } private JobProfiler profiler; protected override void OnStart(string[] args) { try { profiler = new Profiler(MaxThreads); ThreadPool.QueueUserWorkItem(DoWork); // main thread set up thread for work } catch (Exception ex) { LogError(ex); Stop(); } } protected void DoWork(object data) { while (!IsExiting) { try { profiler.RunProfiles(profiles); //this should wait until all child threads are done Thread.Sleep(ThreadSleep); //sleep before next iteration } catch (Exception ex) { LogError(ex); errorCount++; if (errorCount &gt; 10) //if 10 serious errors happen stop the service { IsExiting = true; break; } } } } protected override void OnStop() { try { if(profiler != null) profiler.IsExiting = true; //setting a variable here to signal all remaining threads to stop //here it should be waiting for the main and child threads to finish base.OnStop(); } catch { base.OnStop(); } } //profiler class //****************************************************** private readonly Semaphore _throttle; //setting up a throttle for the number of threads we will allow to execute at once public void RunProfiles(List&lt;Profiles&gt; profiles) { foreach (var profile in profiles) { if (IsExiting) break; //if an exit command is called stop iterating _throttle.WaitOne(); // Wait on a semaphore slot to become available ThreadPool.QueueUserWorkItem(RunProfile, profile ); //then add to thread queue } } private void RunProfile(object profile) { try { var p = (profile as Profile); if (p == null || IsExiting) { _throttle.Release(); // Release the semaphore slot if profile not found or if we're exiting return; } //**** //do a bunch of stuff //**** _throttle.Release(); // Release the semaphore slot } catch (Exception ex) { log.Error(ex); _throttle.Release(); // Release the semaphore slot } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload