I have a thread that reads messages from a named pipe. It is a blocking read, which is why it\'s in its own thread. When this thread reads a message, I want it to notify the Win
In WinForms you can achieve this with Control.BeginInvoke. An example:
public class SomethingReadyNotifier
{
private readonly Control synchronizer = new Control();
///
/// Event raised when something is ready. The event is always raised in the
/// message loop of the thread where this object was created.
///
public event EventHandler SomethingReady;
protected void OnSomethingReady()
{
SomethingReady?.Invoke(this, EventArgs.Empty);
}
///
/// Causes the SomethingReady event to be raised on the message loop of the
/// thread which created this object.
///
///
/// Can safely be called from any thread. Always returns immediately without
/// waiting for the event to be handled.
///
public void NotifySomethingReady()
{
this.synchronizer.BeginInvoke(new Action(OnSomethingReady));
}
}
A cleaner variant of the above which doesn't depend on WinForms would be to use SynchronizationContext
. Call SynchronizationContext.Current on your main thread, and then pass that reference to the constructor of the class shown below.
public class SomethingReadyNotifier
{
private readonly SynchronizationContext synchronizationContext;
///
/// Create a new instance.
///
///
/// The synchronization context that will be used to raise
/// events.
///
public SomethingReadyNotifier(SynchronizationContext synchronizationContext)
{
this.synchronizationContext = synchronizationContext;
}
///
/// Event raised when something is ready. The event is always raised
/// by posting on the synchronization context provided to the constructor.
///
public event EventHandler SomethingReady;
private void OnSomethingReady()
{
SomethingReady?.Invoke(this, EventArgs.Empty);
}
///
/// Causes the SomethingReady event to be raised.
///
///
/// Can safely be called from any thread. Always returns immediately without
/// waiting for the event to be handled.
///
public void NotifySomethingReady()
{
this.synchronizationContext.Post(
state => OnSomethingReady(),
state: null);
}
}