Windows Services and the Main thread - c#

I'm writing a Windows Service in .NET 3.5.
The typical programming model for a windows service is to override the OnStart method to assemble your classes before initiating any long-running processes on another thread.
This is because the OnStart event must return after a default of 30 seconds before a timeout.
In my scenario this thread is vitally important and so I want to create some form of heartbeat system to monitor its state and recycle / recreate it if necessary.
Ideally I would perform this heartbeat check from the main application thread (because the heartbeat must never die) but I do not see how I can marshal any new calls onto that thread.
How would you solve this problem?
Perhaps my intended approach is wrong? If so, how else would you approach it?

Related

Capturing events whenever a new thread starts or ends in C#

I have a highly multithreaded application , where threads are started from multiple places and i would like to know if i can hook into the running process and just get alerted whenever a new Managed Thread is spawned. I should be able to get the following information
The parent thread
New thread
the method from which the new thread is started like <className>.<methodName>
The application is in C# 3.5
As far as I know there is no way to detect when a thread starts. The best solution is probably not to create thread directly, but instead do it via a "thread manager" class that will raise an event when it starts a thread.
State should be handle within the thread processing logic.
I suggest you create a wrapper class which wraps the thread logic and reports it's status and other items as needed. I created such a class for a multi-threaded application where I could corral the status of the threads and pipe that information to the GUI in a standardized way.
Of course I had the luxury of designing it up front, to which, you may not have.

Dispatcher.Invoke 'hangs' during asynchronous read in Windows Service

I've created a Windows service based on the ServiceBase class. In this service I created an instance of the NamedPipeClientStream (m_Stream). After connecting this stream I start an asynchronous read using the BeginRead() method:
m_Stream.BeginRead( m_ReadBuffer, 0, 2, ReadAsyncCallback, m_ReadInfo );
In the callback routine ReadAsyncCallback, which indeed gets called, I call EndRead() for the stream (which gives me the number of bytes read, in this case 2). Next, I want to signal the original thread that the read has been completed. For this I use the Dispatcher.Invoke method:
m_Dispatcher.Invoke( new ReadDelegate( this.OnRead ), bytesRead);
(m_Dispatcher was created in the original thread using System.Windows.Threading.Dispatcher.CurrentDispatcher.)
At this point I expected the OnRead method to get called in the original thread, but it doesn't. The Invoke() method doesn't return, it seems to 'hang'.
I hope someone can help me with this. Please let me know if you need more info, I will try to give it to you asap.
Greetings,
Richard
The System.Windows.Threading.Dispatcher requires a correctly configured SynchronizationContext in order for it to work as you normally expect. When in the context of a WPF application the synchronization context is automatically created for you, however in your Windows Service that does not happen and that's why you see the hang.
Also, aside the synchronization context, since I believe the Dispatcher works in a similar way to the Control.Invoke or BackgroundWorker in Windows Forms, your Windows Service main thread must be pumping a message loop in order for you to be able to inject your call into it.
I have written a blog about how the BackgroundWorker class reacts differently according to the context in which its run (Windows Forms, Console or Windows Service), which you may find to be an interesting read since the mechanism used by that class is similar to the WPF Dispatcher.
Inside BackgroundWorker
Finally, for a more in depth dive into how the synchronization contexts work you should read:
It's All About the SynchronizationContext
The thread that called CurrentDispatcher is probably not pumping messages for some reason. The most likely reason is because it does not have any message pumping mechanism. For Invoke to work correctly the target thread must be specially designed to accept delegate injections. This is usually accomplished by having the target thread spin in an infinite loop waiting for messages to appear in a queue. Another thread would then submit a special message requesting the execution of a delegate. This is all setup automatically on the UI thread of Windows Forms or WPF applications. It will not exist in Windows Service application unless you get it going manually.
I would not attempt to use this delegate marshaling technique (or any technique that synchronously injects a delegate into another thread) anyway. The reason is because it will cause that asynchronous IO callback, which is executing on a ThreadPool thread or IO completion port thread, to block until that marshaled delegate completes. You do not want to tie up the IO in this manner.
Instead you should publish the data that is read from the stream into a shared data structure, like a queue or list, and then have your original thread pick it up on a specific interval. If the original thread is expected to wait for data to be read from the stream then you could setup the producer-consumer pattern. This is pretty easy with the BlockingCollection. The original thread will call Take which will block until an item arrives and the IO callback will publish the data by calling Add.
There are other acceptable ways this could be handled, but calling Invoke is probably not one of them.

C# - Compact Framework Windows CE - GUI Thread Blocks Higher Priority Threads

I am having an issue where I have a Windows CE compact framework Application written in C#, where I have the primary GUI thread set to normal priority and a communication thread set to above normal priority to get as close to pseudo real time performance. The issue I am having is within a button handler I run a loop to load config data from a file to the GUI before allowing it to be edited. This takes around 2-3 seconds to complete. While this blocking in the event handler is happening, my higher priority communication thread is being blocked. There are no locks are thread syncs in place. The communicatio thread has no dependencies on the GUI thread.
This is how I spawn my comm thread:
MbWorkerThread = new Thread(MbPollingThread);
MbWorkerThread.IsBackground = true;
MbWorkerThread.Priority = ThreadPriority.AboveNormal;
MbWorkerThread.Start();
It is an MTA application. Also, I have tried to use Thread.Sleep(1) in the GUI event handler to yield to the higher priority thread and it does not work. I also tried using signals to yield to the higher priority thread, and that does not work. The only thing that works is if I place Application.DoEvents() in the loop while loading config in the event handler. This of coarse whas just a test, as I do not want to sprinkle Application.DoEvents() throught my code to make it work since I know Application.DoEvents() is dangerous.
My understanding is that the primary GUI thread is a foreground thread, but a thread none the less. Also, I have made the communication thread a background thread just to allow it to be killed when the primary thread is exited.
I have tried everything, I have search the Internet endlessly before asking this question.
Any help will be greatly appreciated.
P.S. - I though about a form timer but I know it runs in the GUI thread so that would not help. I though about another thread but I really did not what to marshall GUI updates via Invoke.
Your program starts in Main(), where you typically call Application.Run( new MyForm() ). Application.Run() implements the standard Windows Message Pump, which deals with messages from the OS and other applications, including user input, inter-process communication, repaint requests, etc.
GUI events, like Button click, are dispatched via this thread. If you perform long-running work in an event handler, other messages are not being processed.
Application.DoEvents() blocks the calling thread, and waits for all pending messages to be processed. If DoEvents helps your communication thread when Sleep(1) did not, then I suspect there is a dependency between your communication thread and the GUI/Message Pump thread.
Even if this is not the case, it is not a good idea to block the GUI thread. Move your file loading into the background with ThreadPool.QueueUserWorkItem() and marshal the results back to the UI at the end with Invoke or BeginInvoke.
BeginInvoke instead of Invoke fixed the issue. Thanks for the replies.

interface freezes in c# multi-threaded app

I have a c# .NET multi-threaded application that is freezing the interface. What is unusual about this is that the interface does not freeze unless I let the system sit idle long enough for the screen saver to start (which requires me to reenter my password to re-gain access to the system). When the interface becomes visible again (after I have successfully entered my password) all the windows are white. I can see the window titles, move the windows around, minimize them and such, but the screens are not repainting. When I break all and enter the debugger, the call stack has Application.Run(), external code, and then "in a sleep, wait, or join". I put break points in all four of the threads I open and they are still running, it is just the main app's UI thread that is blocked. When I look at my thread list, what was my main thread and my four worker threads now consists of my main thread and 11 worker threads. I didn't open this many threads so it must be the serialport class.
Now let me describe my program.
My main app allows users to collect and monitor data from serial ports. I have implemented this in the following way. When a connection is desired, a button is pressed on the main app which calls a function in a DLL which opens a status window and then launches a thread which monitors the serial port. When that function returns, the main app launches a thread to monitor a queue created in the DLL when it is initialized. When data is received from the serial port, the data is parsed and then the status window is updated (via a delegate) and the data is pushed onto the queue. When the main apps worker thread sees data in the queue it retrieves it and posts it in a list box on the main app, using a delegate. In all cases I use BeginInvoke to call these delegates.
My DLL contains two libraries for the two different types of equipment it can communicate with.
This problem occurs when I have a connection to two devices; hence the four worker threads two for each device. The DLL itself is setup as a comm object so I can access it easily from a C++/MFC app and a c# app, both of which utilize it.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would appreciate any suggestions you might have. Thanks.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would recommend running your program under the new Visual Studio 2010 Concurrency Profiler. This will show you, at runtime, which threads are blocked, and which objects they are waiting on. Thread contention is explicitly marked and highlighted for you.
You can use this to easily determine what code is causing the deadlock on your UI thread.
Try changing your Thread Start code to Thread.Start() instead of BeginInvoke(). BeginInvoke does not keep threads tryky seperate from your UI, as it and it may be interacting strangely with DoEvents. You can read up on BeginInvoke and how it works here: http://www.codeproject.com/KB/cs/begininvoke.aspx
Also, DoEvents is NEVER necessary in an application, and can cause a lot of unexpected behavior. Use threadding with UI calls wrapped in a Control.Invoke(...) statement. If you're using .NET 3.5+, you can make this easy with delegates that look like this: Invoke((Action)delegate() {*code goes here*});

C# Communication between threads

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

Categories