Dispatcher.Invoke 'hangs' during asynchronous read in Windows Service - c#

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.

Related

Is rampant use of Control.Invoke and Control.InvokeRequired healthy?

I am writing a client server application that works like this:
Form1 loads and creates ServerHost. ServerHost is started to listen for TcpClient connections, on connected and accepted, ServerHost spawns a thread by way of ThreadPool.QueueUserWorkItem(DoWork, client);
Within the DoWork() thread, I want to update Winform Controls on Form1.
This is achieved by having events in ServerHost such as ServerHost.SomethingHappened. When something happened in DoWork(), it raises the event and the Form1.Handler is called to update the winforms control.
This set up gives me cross-thread operation error.
Is use of Control.Invoke and Control.InvokeRequired healthy? I am not good at threads, and MSDN is saying to use BackgroundWorker, but I can't see how to do it here. Any advice to change the structure to avoid using Invoke in this set up?
Control.Invoke is highly questionable, and Control.InvokeRequired is downright toxic.
If at all possible, use the new async/await support, and you won't need to explicitly marshal back to the UI thread. Also, use Task.Run instead of ThreadPool.QueueUserWorkItem for background work.
The problem with Control.Invoke is that it ties your library to a specific UI (WinForms). Capturing a SynchronizationContext is a step above that, and implicitly capturing the SynchronizationContext by using await is even better.
You have to invoke the code that updates the user interface on the UI thread.
In general there are several options to do that:
calling Invoke on a Control
using a BackgroundWorker that has been started on the UI thread
calling Post on the SynchronizationContext of the UI thread
using Task.ContinueWith with the TaskScheduler of the UI thread
using asynchronous calls with async/await
In my opinion last method is by far the easiest for the developer, but it is only available with C# 5 and .NET 4.5 or .NET 4.0 with the Microsoft.Bcl.Async package. Tasks are nearly as easy to use but both of these methods would require you to change your code. They won't work to simply invoke a method on the UI thread from a thread pool thread.
The BackgroundWorker is usually used to schedule an action that takes quite some time. Its ReportProgress method raises the ProgressChanged event on the thread that called the RunWorkerAsync method. As such it is also not a good solution to your problem.
SynchronizationContext.Post and Control.Invoke work similarly, but Control.Invoke doesn't require you to capture the UI context, so it's easier to use.
To summarize it you should use Control.Invoke unless you want to change your code to make use of async/await.
It's fine as long as the UI thread isn't overburdened by those invokes. It does introduce some latency to the communication, which usually isn't an issue, however, it can become more of a problem if you're doing a lot of Invokes, or if the UI thread is doing a lot of work (eg. rendering complex graphs or something like that). Invoke is a synchronous method - it will not return until the invoked command is actually processed, and returns its return value.
As long as you're not tied up by these issues, all is well. Profiling and performance testing is critical to allocate your resources correctly, guessing is usually a huge waste of time and resources.
If you don't need the resulting value (or at least not synchronously) and you're starting to get into performance trouble, have a look at BeginInvoke, which handles the invoking asynchronously. This means your networking thread doesn't have to wait for the UI thread to work. This is quite critical in high performance servers with thousands of connections. They simply can't afford to wait while the UI does its thing.
However, do note, that having a server socket running on a different thread is not a good solution for larger servers, and in fact, it's no longer the easiest solution either. .NET now has great support for asynchronous calls and callbacks, making implementations of asynchronous processing a breeze. In your typical Winforms application, it means that I/O blocking applications can work without having constantly running and polling threads. For example, waiting for a new connection can be as simple as:
var connection = await listener.AcceptTcpClientAsync();
That's it. Automagically, all the callbacks will be processed at the right time, without blocking the processing, all of your own code always running on the main UI thread. In other words, you can easily do this:
while (!aborted)
{
var connection = await listener.AcceptTcpClientAsync();
tbxLog.Text += "New connection!\r\n";
}
While this seems like an infinite loop blocking the UI thread indefinitely, the reality is that when the application gets to the await keyword, it will register an asynchronous callback and returns. Only when the asynchronous callback is actually invoked (by IOCP in this case) is the code resumed (on the UI thread), and tbxLog has the text appended, followed by waiting for another connection.
I've never had problems doing it this way. No matter how you set it up, updating your controls has to be done on the thread they were created on. If you use a BackgroundWorker or some other async construct, somewhere an invoke is going to be called. I typically create a method on the form like:
delegate void TextSetter(string text);
internal void SetText(string text)
{
//call on main thread if necessary
if (InvokeRequired)
{
this.Invoke((TextSetter)SetText, text);
return;
}
//set the text on your label or whatever
this.StatusLabel.Text = text;
}
I've used that method in a number of applications and it's never been a problem, even updating many times per second.
As far as I'm aware, the only way to get around calling an invoke is to have your main thread constantly poll for updates, which is generally accepted as a really bad way to do things.
A really obvious simplification is to abstract away the InvokeRequired/Invoke into an extension method for a Control.
public static class FormExt {
public static void Execute(this Control c, Action a) {
if (c.InvokeRequired) {
c.Invoke(a);
} else {
a();
}
}
}
Now you just wrap up normal form updates into a lambda and execute them.
form1.Execute(() => form1.Text = "Hello world");

Reuse an awaiting thread

So, as everyone knows, frameworks like asp.NET, WPF and WinRT manage one or more threads for you. In asp.NET, the framework pools a set of threads that take requests from a queue and process them. In WPF, the framework manages the UI thread for you, which takes messages from the message pump.
This can be achieved with a simple producer/consumer approach, where the consuming thread executes a while(true) loop, takes messages from a queue and uses a message handler (the user's code) to execute them. Simple enough. You can find a basic implementation here: https://stackoverflow.com/a/5828863/857807
With the introduction of the async/await semantics, you can delegate CPU/IO-intensive work to some other thread, and leave the (for example) UI thread responsive. This means that the UI thread will keep taking messages from the pump.
My question is: starting with the aforementioned basic implementation, how would the consumer implement this? How would you know that the message handler is asynchronously awaiting for another thread to complete and, therefore, take another message from the queue? I'm sure I'm missing something big here.
The key is that when an async method yields in an await, it actually returns to its caller. So, from the perspective of the main loop, the method has completed.
Later on, when the awaitable operation completes, it schedules the remainder of the async method to the captured context. In the cases you mentioned (ASP.NET / WPF / WinRT), the context is a SynchronizationContext. In the UI frameworks (WPF / WinRT / WinForms / etc), that SynchronizationContext is tied to the message queue.
So if you want an async-compatible "main loop", you'd need to implement a custom SynchronizationContext that allows scheduling delegates back to that main loop.
For more information:
My async intro describes how async and await methods return and capture context.
My SynchronizationContext MSDN article describes the relevant portions of that type, and how it's used throughout the .NET framework.
My AsyncEx library has an async-compatible "main loop", including documentation, source, and unit tests.

ReadToEndAsync from UI Thread

If I call await ReadToEndAsync from the UI thread on Windows Phone 8, on what context will ReadToEndAsync do its work? Will a task get queued for processing by the UI thread itself, or will a new thread do the work.
Based on this:
http://blogs.msdn.com/b/ericlippert/archive/2010/11/04/asynchrony-in-c-5-0-part-four-it-s-not-magic.aspx
it seems like it will run on the UI thread.
This is an essential truth of async in its purest form: There is no thread.
For a truly asynchronous stream, ReadToEndAsync has no almost work to do. When you call that method, it merely asks the runtime to read to the end, and notify it when the operation is complete (via a Task). The runtime turns to the OS, asks it to read, and notify it when the operation is complete (e.g., via an IOCP). The OS turns to the device driver, asks it to read, and notify it when the operation is complete (e.g., via an IRP). The device driver turns to the device, asks it to read, and notify it when the operation is complete (e.g., via an IRQ).
There is no thread.
This is an ideal situation, of course. In the real world, at some point the "read to end" operation is broken up into several "read n byte" operations, and those need to be stitched back together. That (tiny) amount of work is done using borrowed threads: unknowable threads for kernel-mode code and thread pool threads for user-mode code.
Also, there are some situations where an asynchronous API does not exist. In those cases, asynchronous work is faked using a thread pool thread. For example, if you call ReadToEndAsync on a MemoryStream, there are no asynchronous APIs for reading from memory, so that is a fake asynchronous operation that will run on the thread pool.
But the idea that there always must be a thread to execute an asynchronous operation is not the truth. Do not try to control the thread — that's impossible. Instead, only try to realize the truth: there is no thread.
Edit: Expanded this answer into a blog post.

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

Winforms should I multi thread or use event timer?

I currently have a thread that listens for data from the network and then runs rules on it. I then want to pass the data to the GUI. I am worried about having a deadlock in the GUI. I cant figure out were to put the mutexes on the GUI side. I am also using c# and dotnet 3.5.
What I have come up with is
1) Using a timer to create an event and dump the thread. Worried about performance.
2) Use an intermediary event to copy the data to GUI.
3) Dig in and figure out thread safe way of using GUI.
What do you think is best way to proceed?
Edit: Here is the solution I am using. I pass in the changed element and then protect the big object with a mutex. I use helper function to switch threads using InvokeRequired then BeginInvoke with a delegate. Pulled from reading the answers and then following links until reaching Threading in Windows Forms by Jon Skeet.
delegate void UInt32ParameterDelegate(UInt32 n);
public void UpdateLocation(UInt32 n)
{
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
return;
}
// Must be on the UI thread if we've got this far
this.engine.location.UpdateBusy.WaitOne();
// do the work in here
this.engine.location.UpdateBusy.ReleaseMutex();
}
Synchronization is very easy in Windows Forms. You can call Control.Invoke() in the background thread. The thread will stall until the delegate has finished running on the UI thread. No sync required at all.
If stalling the thread is a problem, use Control.BeginInvoke(). You'll have to protect the object(s) you pass to the delegate with a lock if the thread might alter them while it continues running. That's rarely the case in a producer-consumer scenario, the thread can simply create new objects.
Do make sure that you don't Invoke() too often. Do it more frequently than about 1000 times per second and the UI thread will stop pumping Windows messages, being bogged down by handling the invoke requests. Since it is human eyes you're trying to please, invoking more than about 25 times per second is just wasted effort. Pool intermediate results in a collection object.
I hope I understand your problem correctly.
After the background thread reads the data and does whatever it wants, it should use Invoke to call a method on the GUI thread. That method would update anything that should be updated in the GUI.
Never read from the network on the GUI thread. It's only a matter of time before your application runs during a network outage and your GUI hangs as a result. This will really frustrate your users.
In your situation I think the best approach is to have a background thread complete the read operation. Then take the resulting data and move it back to the GUI thread via a SynchronizationContext Post or Send method.
you should just pass an event from your network thread to your UI thread.
then cross threads using begininvoke so you don't get a cross thread exception.
Need help getting info across a UI thread and another thread in C#
You could use a backgroundworker that will process the datareading in a background thread and when it's done you can end the backgroundworker triggering it's RunWorkerCompletedEventHandler. In the RunWorkerCompletedEventHandler you can update your GUI thread with the result.
Isn't easier to just throw a delegate who raise an event that inform the form to refresh itself?

Categories