Note that there are some explanatory texts on larger screens.

plurals
  1. POC# WinService with Timer-controlled threadpool operations
    primarykey
    data
    text
    <p>I have got a Windows Service class ( inherits from ServiceBase ) which at construction time is provided with a List of objects. Each Operation describes a DoWork() virtual method.<br> The point of of the Service class is to manage all the underlying Operations, add/remove them to the List at runtime and execute their DoWork() method in a ThreadPool thread.<br> Each Operation has a System.Timers.Timer object which is instantiated and run with the Operation class. Each Operation exposes up an event to signal the managing class that its own timer is up and it has to fire its own DoWork() method in a thread.</p> <p>The TimedService class binds each elapsed timer event to a method that requests a thread from the pool: </p> <pre><code>private void CheckOperationsList(object source, EventArgs e) { try { foreach (Operation op in this._operationsList) { lock (this._operationsList) { op.TimerElapsed += new Operation.ElapsedEventHandler(this.RequestThreadFromPool); } } } catch (Exception ex) { this._ManEV.WriteError(this._serviceName, ex.Message); } } </code></pre> <p>And of course, the RequestThreadFromPool(object sender, EventArgs e) method does the following thing: </p> <pre><code> ThreadPool.QueueUserWorkItem(new WaitCallback(((Operation)sender).DoWork), new object()); </code></pre> <p>I am receiving weird behavior from the processes. I have tried to implement a dummy Operation with a timer set to 10 seconds which simply keeps the processor occupied for a couple of seconds: </p> <pre><code>for (Int16 i = 0; i &lt; Int16.MaxValue; i++) { for (short j = 0; j &lt; short.MaxValue; j++) { } } </code></pre> <p>Every time an Operation runs alone in the queue ( I pass a List of only one element to the Service ) everything is normal. The process spawns its own thread, keeps the CPU up for a couple of seconds, then leaves. </p> <p>I implemented a lighter version of the dummy method above ( basically the same without the inner loop ) to simulate a lightweight thread.</p> <p>As soon as I get two or more operations in the queue ( with different timers! ) all the threads spawn three or four times and then everything stops.<br> I get no activity at all. In Visual Studio it looks like the Timer of each Operation has stopped ticking - I get no calls to the event, I get no calls to the delegate that is supposed to handle the event; each Operation class has its own timer and always refer to the timer via this. ! </p> <p>I tried monitoring all the catch{}es, and tried wrapping each DoWork() method in a try{} , but I am getting no exceptions.</p> <p>What is puzzling me is that if I run several identical Operations ( i.e. two or three long operations or two or three short ones ) everything runs as normal. Looks like as the Event comes from another class, everything gets messed up.</p> <p>I am starting to think that the System.Timers.Timer class is the cause of all the above - I have tried calling Stop() to the timer right before calling the Event, but to no avail. I get 4-5 iterations of each Operation's DoWork() method and then everything quites down. </p> <p><em>edit</em> I forgot to clarify: Each Operation I run is inherited from the base Operation. I.e: </p> <pre><code>public class TestLongOperation : Operation { public TestLongOperation(double secondsInterval) : base(secondsInterval) { } public override void Work(object buh) { for (Int16 i = 0; i &lt; Int16.MaxValue; i++) { for (short j = 0; j &lt; short.MaxValue; j++) { } } } </code></pre> <p>}</p> <p>Any suggestions? I can provide more code if the above is not sufficient. Thanks in advance.</p>
    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.
 

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