I have a thread which grabs some data from network or serial port. The thread must terminate (or return false) if no data is received within 5 seconds.
In other words, if running the thread is taking more than 5 seconds it must stop.
I am writing in C#, but any .NET language is OK.
There are two approaches:
1. Encapsulated timeout
The thread reading the data from network or serial port can measure time elapsed from its time of start and wait for the data for no more than the remaining time. Network communication APIs usually provide means to specify a timeout for the operation. Hence by doing simple
DateTime
arithmetic you can encapsulate timeout management within your worker thread.2. External timeout
Use another thread (or do it in the main thread if that's feasible) to wait for the worker thread to finish within a certain time limit, and if not, abort it. Like this:
Recommendation: I'd stick with the first solution, as it leads to cleaner and maintainable design. However, in certain situation it might be necessary to provide means for 'hard' abort of such worker threads.
Either mechanism should allow you to specify a timeout on the read. For example, you could set
NetworkStream.ReadTimeout
to 5000 before performing the read. You should be able to do something similar for serial ports.A read that has timed out will return 0 from
Stream.Read()
-- this is how you can tell if a timeout actually occurred.Note that using
Thread.Abort()
is deprecated as of .NET 2.0 for some serious problems it can cause. You could theoretically useThread.Interrupt()
, but this will not do anything when the thread is blocked in unmanaged code (including I/O). Using read timeouts is the proper way to solve this problem.If you are using managed code to block the thread, you can use
Thread.Abort
to abort the execution. If you are using 3rd party code or COM interop, there is no way of terminating the thread execution. The only way is setting theThread.isBackroundThread
to true, and then terminating the Process...I guess a watcher thread is what you need. Start another thread at the same time and passes the serial port thread as parameter of that thread. Start the watcher with a five second sleep and check the status of the thread.
Now as for terminating the thread, see alex's answer, its just right !
You mentioned you are reading from a "network". If you are using
NetworkStream
to read you can specify theReadTimeout
to be 5000 (it is in milliseconds). That will wait for 5 seconds then return after that if no data has been read. However if it is in the process or reading I think it might return also so be careful. I've never done anything with the serial API so I'm not sure if there is a setting in there like that.This is a two thread solution.
Example:
Remember:
It is a bad practice to use a method like this. Calling
Thread.Abort()
is not recommended approach. UseThread Synchronization
usingWaitHandles
instead. For example,AutoResetEvent
.