|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Thread terminationIn the below example, what is the preferred approach to ending the thread execution from the Dispose method? Using Thread.Abort would be one appraoch. Changing while(true) to while(SomeVariable) and then control SomeVariable from dispose(..) would be another way. Maybe using some sort of synchronize mechanism also would work? What do you recommend? Thread pollDeviceThread = new Thread(new ThreadStart(PollDevice)); private void PollDevice() { while(true) { // Do work Thread.Sleep(POLL_DEVICE_UPDATE_TIME); } } protected virtual void Dispose(bool disposingManagedResource) { } On Mon, 08 Dec 2008 01:06:42 -0800, RedLars <Liverpool1***@gmail.com>
wrote: > Hi, Instead of Thread.Sleep(), you can use something like WaitHandle.WaitOne() > > In the below example, what is the preferred approach to ending the > thread execution from the Dispose method? Using Thread.Abort would be > one appraoch. Changing while(true) to while(SomeVariable) and then > control SomeVariable from dispose(..) would be another way. Maybe > using some sort of synchronize mechanism also would work? What do you > recommend? with a timeout equal to your "POLL_DEVICE_UPDATE_TIME". Then in the Dispose() method, set the WaitHandle (for example, use an AutoResetEvent). You can combine this with a volatile flag as well, or you can just rely on the return value from WaitOne() (which will tell you whether it timed out or you were signaled by the WaitHandle) to know when to break out of the loop. Using a flag would allow you to ensure that even if the signaling of the WaitHandle loses the race with the timeout that you exit immediately, but it's probably the case that polling the device one extra time before the thread exits is not a problem. Note here that I'm assuming terminating the thread from the Dispose() method is the right thing to do, as is polling your device rather than using some other form of i/o. For example, you've got some object that wraps your device and incorporates internally a thread to support the public interface offered by the class, a thread that needs to be shut down when the class is disposed (though maybe even in that case, that would be a rare example of a case where having a finalizer but no Dispose() method might make sense, providing a different, clearer public interface for shutting down the polling). Pete
Show quote
Hide quote
On 8 Des, 10:42, "Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote: Thanks for the reply Pete.> On Mon, 08 Dec 2008 01:06:42 -0800, RedLars <Liverpool1***@gmail.com> > wrote: > > > Hi, > > > In the below example, what is the preferred approach to ending the > > thread execution from the Dispose method? Using Thread.Abort would be > > one appraoch. Changing while(true) to while(SomeVariable) and then > > control SomeVariable from dispose(..) would be another way. Maybe > > using some sort of synchronize mechanism also would work? What do you > > recommend? > > Instead of Thread.Sleep(), you can use something like WaitHandle.WaitOne() > with a timeout equal to your "POLL_DEVICE_UPDATE_TIME". Then in the > Dispose() method, set the WaitHandle (for example, use an AutoResetEvent).. > > You can combine this with a volatile flag as well, or you can just rely on > the return value from WaitOne() (which will tell you whether it timed out > or you were signaled by the WaitHandle) to know when to break out of the > loop. Using a flag would allow you to ensure that even if the signaling > of the WaitHandle loses the race with the timeout that you exit > immediately, but it's probably the case that polling the device one extra > time before the thread exits is not a problem. > > Note here that I'm assuming terminating the thread from the Dispose() > method is the right thing to do, as is polling your device rather than > using some other form of i/o. For example, you've got some object that > wraps your device and incorporates internally a thread to support the > public interface offered by the class, a thread that needs to be shut down > when the class is disposed (though maybe even in that case, that would be > a rare example of a case where having a finalizer but no Dispose() method > might make sense, providing a different, clearer public interface for > shutting down the polling). > > Pete So basically WaitHandle contains both the timer and the termination mechanism rolled into one. How would the dispose logic work for this scenario? How can I both signal the thread to terminate and dispose of the AutoResetEvent object? Tried to illustrate my point below, the autoResetEvent.Dispose () method shouldnt really be called before the poll-thread has received the automResetEvent signal and terminated. protected virtual void Dispose(bool disposeManagedResources) { if (!(disposed)) { if (disposeManagedResources) { /* Signal thread to terminate */ autoResetEvent.set(); /* Release resource - this cannot work??? */ autoResetEvent.Dispose(); } } } On Mon, 08 Dec 2008 02:42:35 -0800, RedLars <Liverpool1***@gmail.com>
wrote: > So basically WaitHandle contains both the timer and the termination Close enough. :)> mechanism rolled into one. > How would the dispose logic work for this scenario? How can I both Well, as I hinted at before, doing thread signaling in the Dispose() > signal the thread to terminate and dispose of the AutoResetEvent > object? method is a potentially "iffy" operation. This is one of the reasons: to correctly manage it may require other deviations from a proper Dispose() pattern. That said, one possible approach would be for you to let the thread dispose the WaitHandle instance. Another possible approach would be to have the Dispose() method wait on the thread to exit (Thread.Join()), and only dispose the WaitHandle after the thread has exited. Personally, I'd prefer the former...having a Dispose() method able to block in any way just seems wrong to me. It's not that it can't work. It's just that whatever you wind up with, it's not going to be as clean as a normal Dispose() implementation, because you're already doing something unusual in your Dispose() method. Pete
Show quote
Hide quote
On 8 Des, 20:08, "Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote: Thanks for your input.> On Mon, 08 Dec 2008 02:42:35 -0800, RedLars <Liverpool1***@gmail.com> > wrote: > > > So basically WaitHandle contains both the timer and the termination > > mechanism rolled into one. > > Close enough. :) > > > How would the dispose logic work for this scenario? How can I both > > signal the thread to terminate and dispose of the AutoResetEvent > > object? > > Well, as I hinted at before, doing thread signaling in the Dispose() > method is a potentially "iffy" operation. This is one of the reasons: to > correctly manage it may require other deviations from a proper Dispose() > pattern. > > That said, one possible approach would be for you to let the thread > dispose the WaitHandle instance. Another possible approach would be to > have the Dispose() method wait on the thread to exit (Thread.Join()), and > only dispose the WaitHandle after the thread has exited. > > Personally, I'd prefer the former...having a Dispose() method able to > block in any way just seems wrong to me. > > It's not that it can't work. It's just that whatever you wind up with, > it's not going to be as clean as a normal Dispose() implementation, > because you're already doing something unusual in your Dispose() method. > > Pete Would it be better to split the task into two. Use a stop() method that does the signaling to the thread and the dispose does, well, the disposing of AutoResetEvent and other objects? The problem with that approach is that Dispose sort of requires the stop method to be executed to kill the tread before Dispose is executed. Thoughts? On Mon, 08 Dec 2008 22:59:32 -0800, RedLars <Liverpool1***@gmail.com>
wrote: > Would it be better to split the task into two. Use a stop() method One possibility is to throw an InvalidOperationException if Dispose() is > that does the signaling to the thread and the dispose does, well, the > disposing of AutoResetEvent and other objects? The problem with that > approach is that Dispose sort of requires the stop method to be > executed to kill the tread before Dispose is executed. Thoughts? called while the thread is still running. However, I think that's kind of ugly. I think I would have a Stop() method that does the signaling and as I mentioned, lets the thread dispose the AutoResetEvent, and not have a Dispose() method at all. Then the finalizer can just stop the thread, secure in the knowledge that the thread will dispose on the AutoResetEvent on its way out. Pete
Show quote
Hide quote
On 9 Des, 09:10, "Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote: Thanks again for your reply.> On Mon, 08 Dec 2008 22:59:32 -0800, RedLars <Liverpool1***@gmail.com> > wrote: > > > Would it be better to split the task into two. Use a stop() method > > that does the signaling to the thread and the dispose does, well, the > > disposing of AutoResetEvent and other objects? The problem with that > > approach is that Dispose sort of requires the stop method to be > > executed to kill the tread before Dispose is executed. Thoughts? > > One possibility is to throw an InvalidOperationException if Dispose() is > called while the thread is still running. > > However, I think that's kind of ugly. I think I would have a Stop() > method that does the signaling and as I mentioned, lets the thread dispose > the AutoResetEvent, and not have a Dispose() method at all. Then the > finalizer can just stop the thread, secure in the knowledge that the > thread will dispose on the AutoResetEvent on its way out. > > Pete Not sure I follow. Do you mean the spawned thread should clean-up the AutoResetEvent object and not implement IDisposable at all? Would not that break with the rules for when to use IDisposable? On Tue, 09 Dec 2008 02:54:50 -0800, RedLars <Liverpool1***@gmail.com>
wrote: > Do you mean the spawned thread should clean-up the AutoResetEvent Yes.> object and not implement IDisposable at all? > Would not that break with To some extent, yes. But, those rules are simply guidelines and another > the rules for when to use IDisposable? good rule to follow is to not write a Dispose() method that can block. Pick your poison. :) Pete It depends on how long your poll time is. If it is a short time then I
would have a while (!Terminated) { ......... } If it is too long I would create a ManualResetEvent public class MyWorker { private volatile bool Terminated; private readonly ManualResetEvent TerminateResetEvent; public MyWorker() { ..Create the TerminateResetEvent; } public void Execute() { while (!Terminated) { ..Do stuff Monitor.Wait(TerminateResetEvent, poll time); } } public void Terminate() { if (!Terminated) { Terminated = true; TerminateResetEvent.Set(); } } } As usual the code is just an idea, probably not compilable etc.
Show quote
Hide quote
On 8 Des, 10:54, "Peter Morris" <mrpmorri...@SPAMgmail.com> wrote: Thanks for the reply.> It depends on how long your poll time is. If it is a short time then I > would have a > > while (!Terminated) > { > ......... > > } > > If it is too long I would create a ManualResetEvent > > public class MyWorker > { > private volatile bool Terminated; > private readonly ManualResetEvent TerminateResetEvent; > > public MyWorker() > { > ..Create the TerminateResetEvent; > } > > public void Execute() > { > while (!Terminated) > { > ..Do stuff > Monitor.Wait(TerminateResetEvent, poll time); > } > } > > public void Terminate() > { > if (!Terminated) > { > Terminated = true; > TerminateResetEvent.Set(); > } > } > > } > > As usual the code is just an idea, probably not compilable etc. > > -- > Pete > ====http://mrpmorris.blogspot.comhttp://www.capableobjects.com Timeout in this particular instance is10 seconds. > Timeout in this particular instance is10 seconds. It's not how long it is that really matters, it's how long you think is acceptible to wait :-) On 8 Des, 12:18, "Peter Morris" <mrpmorri...@SPAMgmail.com> wrote: Thanks for the example code.> > Timeout in this particular instance is10 seconds. > > It's not how long it is that really matters, it's how long you think is > acceptible to wait :-) > > -- > Pete > ====http://mrpmorris.blogspot.comhttp://www.capableobjects.com
Other interesting topics
A good .net obfuscator
not all code paths return a value It Won't Load My Assembly And It Won't Say Why windows service : allow service to interact with desktop & SendKeys.SendWait ? accessing non-static members from static method communicate with the BackgroundWorker moving to next record in a Generic Collection MSXML COM Object Extension methods performance static method |
|||||||||||||||||||||||