Thread Management
-
I need to read certain data from an external source for the duration of an application's run time. In order to do that, I set up a thread that starts as soon as the first form on the application loads and that will continue to run until that form is null. Now, for most of the application run time, the values that I'm reading from the external source should be static (or nearly so), but the operator of the software will initiate a process (a test) during which the values I need to read will change. Ideally, I would still get those values from the external source from the separate thread, but I encountered some serious reduction in program efficiency when I did that. The test itself runs on its own thread so that the operator can switch between different forms on the application while the test is running. When the test thread and the other thread that runs for the duration of the application were both competing to read from/write to the external source, I had the slowdown mentioned previously. I solved the reduction in efficiency problem by having the test thread suspend the execution of the other thread until it finished its work, but encountered some problems after doing that which aren't obviously related to the thread suspension, but may be the culprit behind the problems I'm encountering. Is there a problem with one thread (not the main thread) suspending and then resuming the execution of a different thread (that is also not the main thread)?
-
I need to read certain data from an external source for the duration of an application's run time. In order to do that, I set up a thread that starts as soon as the first form on the application loads and that will continue to run until that form is null. Now, for most of the application run time, the values that I'm reading from the external source should be static (or nearly so), but the operator of the software will initiate a process (a test) during which the values I need to read will change. Ideally, I would still get those values from the external source from the separate thread, but I encountered some serious reduction in program efficiency when I did that. The test itself runs on its own thread so that the operator can switch between different forms on the application while the test is running. When the test thread and the other thread that runs for the duration of the application were both competing to read from/write to the external source, I had the slowdown mentioned previously. I solved the reduction in efficiency problem by having the test thread suspend the execution of the other thread until it finished its work, but encountered some problems after doing that which aren't obviously related to the thread suspension, but may be the culprit behind the problems I'm encountering. Is there a problem with one thread (not the main thread) suspending and then resuming the execution of a different thread (that is also not the main thread)?
You can certainly use multiple threads but using the Suspend and Resume requires more management and overhead than keeping your threads event driven. Personally I prefer using mutexes and semaphores which under C# translate to AutoResetEvent/ManualResetEvent and Synhronized.Queue. The basic idea is to keep you recv thread doing one thing very well: reading packets. But how do you process those packets and keep performance decent. You have a couple options. For one you could use a Synchronized Queue where the Receiver reads and enqueues raw messages and the signal readiness via the Auto/ManualResetEvent.Set() function. This causes a worker thread to wake up from a Auto/ManualResetEvent.WaitOne(). Now depending on your architecture you can even pool threads to do concurrent processing of the messages and their payloads. I'd be careful about the total amout of worker threads as there is a point of diminish returns plus CPU overhead. But the basic idea is to pre-allocate a pool of threads that would wakeup and process a message. There is a good article and code example you can find under TCP Servers QIO. Now the other thing to consider is using the Async architecture instead of a multi-threaded architecture. Many people subscribe to this model for I/O intensive apps such as Web servers. From a code standpoint, you may be able to reduce the complexity of the app by moving to a Async Model. Again there are numerous examples under the TCP Server topic. Ultimately you need to choose the model that fits your requirements and the intended hardware. Too much threading and you can hog a CPU pretty quick. Besides when you use C# sockets they are multi-threaded under the hood and designed for optimum efficiency. At the end of the day I generally prefer Async but use QIO for specialized situations such as discovery processing, DB interfaces, etc. Mike