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 thread that called
CurrentDispatcheris probably not pumping messages for some reason. The most likely reason is because it does not have any message pumping mechanism. ForInvoketo 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
ThreadPoolthread 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 callTakewhich will block until an item arrives and the IO callback will publish the data by callingAdd.There are other acceptable ways this could be handled, but calling
Invokeis probably not one of them.