My program uses a producer/consumer pattern, meaning that my producer adds tasks to a queue and my consumer executes those tasks in the background whenever there's something in the queue to execute.
My worker thread needs to use a serial port, and the standard way of using a serial port is to open it at the start of the program and keep it open for as long as it's needed (until shutdown). My program is an always-on web service, where usually objects have a lifetime scoped to the request. These two things contradict each other somewhat, so I need to make sure that when I get a request, the background thread is up and running and holding the serial port open instead of opening it for every request which might be more natural in most cases. So my program needs a high degree of self-sufficiency, it needs to detect errors in the worker thread and restart it if needed.
Is there a technique for guaranteeing that my worker thread stays up? I have considered wrapping the entire worker thread's code in a try/catch, and sending an event to the main thread in the finally block so that the worker can be restarted. Or I could continually send "ping" events to the main thread to let it know that the worker thread is still running, or even poll the worker thread from the main thread.
Is there a standard way of doing this? What's the most robust approach? Note that it's fine if the worker thread dies or becomes unable to complete its work for whatever reason - I will just restart the thread and keep trying, however ideally if that happens it should be able to put its task back in the queue.
Examples in C#/F#/dotnet (framework) are greatly appreciated.
Related
I'm creating an application that's going to be continuously listening out for incoming signals via TCP until it's either stopped via a button, or the application closes. Being as the PC that the application is running on needs to run quite CPU-heavy stuff, I figured I should run this in a separate thread so that it doesn't hog the CPU.
My thoughts are to use a BackgroundWorker containing an inner-loop in DoWork() that checks the IsCancellationPending flag (this is set via the CancelAsync() method when the user clicks the stop button or exits the application). Is this the best route to go, or is there some other method that's more accepted?
You're doing an IO bound operation, so you shouldn't even be using another thread at all. You should be handling the work asynchronously, in which an event, callback, Task, etc. fires to indicate that you have a message to process, which you can process and then go back to not using any thread at all.
Creating a thread that's just going to spend the vast majority of its time sitting there doing nothing while you wait for network activity isn't a productive use of resources.
I'm writing a server in C#. The asynchronous example on msdn.microsoft.com suggests the following.
BeginAccept to listen for client (& start a new thread when client calls).
BeginReceive to receive the data from client ( & start a new thread to do it on).
BeginSend to reply to send data to client ( & start yet another thread to it on).
At this point there seems to be 4 separate threads, when from my (possibly naive) point of view there really only needs to be 2. 1 for the server to keep listening on and 1 for the conversation with the client. Why does my conversation with the client need 3 threads since I have to wait for a reply before I send and I won't be doing anything else while waiting to receive data from the client?
Cheers
BeginAccept does not start a new thread. It is attaching a handler to an OS level hook. No thread is going to be doing the meat of the work for this operation. The same is true for BeginReceive and BeginSend. None of these are starting new threads.
When the events that they are adding handlers for actually fire, then a thread pool thread is created to respond to the action happening. The CPU bound work done here should generally be quite low. What you'll see here is a lot of thread pool threads requested, but very little work being done by them, so they are sent back to the pool very quickly.
The thread pool is designed for this type of use. Rather than creating full threads for each event response (which would be expensive) you can create just 1-2 threads and continually re-use them to respond to all of these events in turn. The pool will only create as many threads as it needs to keep up with a sufficiently small backlog.
While your main thread will be marshalled around these operations, you should not have to "start a thread" yourself.
BeginAccept is a non blocking method - .NET will return immediately from it but invoke your callback on the thread pool when it fulfils its purpose asynchronously.
The threadpool is optimised outside of your control.
I have a basic C# console application that executes a fairly long running process involving timers and asynchronous requests. The sole purpose of the Main() method is to initialize the timers and then let them do their thing for the next few hours.
I know that Windows Services are appropriate for many long running processes, but doesn't feel appropriate for this use case (executed manually when needed, always terminated within a day, no hurdles of having to install the Service, etc).
Right now, I simply do:
while (true)
Thread.Sleep(5000);
Throwing in a Thread.Sleep seems ... dirty for some reason. Or is that really the best thing to do to stop the application from terminating before the async process are complete?
You could use one/multiple ManualResetEvent to communicate from the background threads to the foreground thread.
The foreground thread in Main could wait until all background threads signaled that they are finished.
You shouldn't be Thread.Sleep, but isntead you should be waiting on some sort of event that would get signaled when there is anything to do, including shuting yourself down.
The application you describe though would much better fit as a service, not as a console app.
I have a windows service doing some repetitive work (wcf calls) after logging programmaticaly at a web server. All calls are invoked through various threads running dependently in parallel, but if for example, the connectivity is lost, or the iis recycles, hence the inproc session management directs me to re-login, I want to handle this exception, halt all other threads, propagate the exception up to main thread, retry to login and upon success to signal all threads to restart.
My main application is something like the following. I login, I start two workers and the exception handling mechanism in main thread is pending:
IFileManagerService fileManagerService = new FileManagerService();
IJobManagerService jobManagerService = new JobManagerService();
WindowsServiceSettings.AuthenticationService.Login(WindowsServiceSettings.Credentials.Split(':')[0], WindowsServiceSettings.Credentials.Split(':')[1]);
WriteToLogFile("Service Started at " + DateTime.Now);
fileManagerService.Start();
jobManagerService.Start();
Can I implement this via wait handles and how am I going to?
Thank you very much!
First, you need a way to propogate exceptions across threads. By far the easiest way to do this is to make your child threads into Task objects. You can then give these tasks a continuation to detect if any of them error out.
The second thing you'll need is a way to cancel the other threads. Use cooperative cancellation with the same CancellationToken. When the task continuation detects an error, it should cancel all the other threads (and wait for them to complete).
From there, it's a simple matter of having the task continuation re-login and then restart the tasks (including registering itself as a task continuation for the new tasks).
For a .Net 3.5 project, I'd use a callback method from a worker thread to signal the main thread that there's a problem. Have each worker invoke a separate "heartbeat" callback method that periodically checks with the main thread for permission to continue; a worker could be called from various places in its processing loop.
If the main thread receives an error callback, then it can set the heartbeat method to return a stop indication, letting each worker thread safely stop itself. When the worker stops, have it calls a termination callback that passes the thread's ManagedThreadId, which the main removes from a collection of active threads. Once the collection count is zero then all of the workers are done. This avoids having to rely on Thread.Abort().
If needed, you could use the heartbeat to reset a timer for each active thread, which could alert the main thread if a worker hangs. The heartbeat could also be used to update the main thread with worker progress.
I am using .NET 3.5 and am trying to wrap my head around a problem (not being a supreme threading expert bear with me).
I have a windows service which has a very intensive process that is always running, I have put this process onto a separate thread so that the main thread of my service can handle operational tasks - i.e., service audit cycles, handling configuration changes, etc, etc.
I'm starting the thread via the typical ThreadStart to a method which kicks the process off - call it workerthread.
On this workerthread I am sending data to another server, as is expected the server reboots every now and again and connection is lost and I need to re-establish the connection (I am notified by the lost of connection via an event). From here I do my reconnect logic and I am back in and running, however what I easily started to notice to happen was that I was creating this worker thread over and over again each time (not what I want).
Now I could kill the workerthread when I lose the connection and start a new one but this seems like a waste of resources.
What I really want to do, is marshal the call (i.e., my thread start method) back to the thread that is still in memory although not doing anything.
Please post any examples or docs you have that would be of use.
Thanks.
You should avoid killing the worker thread. When you forcibly kill a Win32 thread, not all of its resources are fully recovered. I believe the reserved virtual address space (or is it the root page?) for the thread stack is not recovered when a Win32 thread is killed. It may not be much, but in a long-running server service process, it will add up over time and eventually bring down your service.
If the thread is allowed to exit its threadproc to terminate normally, all the resources are recovered.
If the background thread will be running continuously (not sleeping), you could just use a global boolean flag to communicate state between the main thread and the background thread. As long as the background thread checks this global flag periodically. If the flag is set, the thread can shut itself down cleanly and exit. No need for locking semantics if the main thread is the only writer and the background thread only reads the flag value.
When the background thread loses the connection to the server that it's sending data to, why doesn't it perform the reconnect on its own? It's not clear to me why the main thread needs to tear down the background thread to start another.
You can use the Singleton pattern. In your case, make the connection a static object. Both threads can access the object, which means construct it and use it.
The main thread could construct it whenever required, and the worker thread access it whenever it is available.
Call the method using ThreadPool.QueueUserWorkItem instead. This method grabs a thread from the thread pool and kicks off a method. It appears to be ideal for the task of starting a method on another thread.
Also, when you say "typical ThreadStart" do you mean you're creating and starting a new Thread with a ThreadStart parameter, or you're creating a ThreadStart and calling Invoke on it?
Have you considered a BackgroundWorker?
From what I understand, you just have a single thread that's doing work, unless the need arises where you have to cancel it's processing.
I would kill (but end gracefully if possible) the worker thread anyway. Everything gets garbage-collected, and you can start from scratch.
How often does this server reboot happen? If it happens often enough for resources to be a problem, it's probably happening too often.
The BackgroundWorker is a bit slower than using plain threads, but it has the option of supporting the CancelAsync method.
Basically, BackgroundWorker is a wrapper around a worker thread with some extra options and events.
The CancelAsync method only works when WorkerSupportsCancellation is set.
When CancelAsync is called, CancellationPending is set.
The worker thread should periodically check CancellationPending to see if needs to quit prematurely.
--jeroen