Can an asynchronously fired event run synchronously on a form?
- by cyclotis04
[VS 2010 Beta with .Net Framework 3.5]
I've written a C# component to asynchronously monitor a socket and raise events when data is received. I set the VB form to show message boxes when the event is raised. What I've noticed is that when the component raises the event synchronously, the message box blocks the component code and locks the form until the user closes the message. When it's raised asynchronously, it neither blocks the code, nor locks the form.
What I want is a way to raise an event in such a way that it does not block the code, but is called on the same thread as the form (so that it locks the form until the user selects an option.)
Can you help me out?
Thanks.
[Component]
using System;
using System.Threading;
using System.ComponentModel;
namespace mySpace
{
public delegate void SyncEventHandler(object sender, SyncEventArgs e);
public delegate void AsyncEventHandler(object sender, AsyncEventArgs e);
public class myClass
{
readonly object syncEventLock = new object();
readonly object asyncEventLock = new object();
SyncEventHandler syncEvent;
AsyncEventHandler asyncEvent;
private delegate void WorkerDelegate(string strParam, int intParam);
public void DoWork(string strParam, int intParam)
{
OnSyncEvent(new SyncEventArgs());
AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(null);
WorkerDelegate delWorker = new WorkerDelegate(ClientWorker);
IAsyncResult result = delWorker.BeginInvoke(strParam, intParam, null, null);
}
private void ClientWorker(string strParam, int intParam)
{
Thread.Sleep(2000);
OnAsyncEvent(new AsyncEventArgs());
OnAsyncEvent(new AsyncEventArgs());
}
public event SyncEventHandler SyncEvent
{
add { lock (syncEventLock) syncEvent += value; }
remove { lock (syncEventLock) syncEvent -= value; }
}
public event AsyncEventHandler AsyncEvent
{
add { lock (asyncEventLock) asyncEvent += value; }
remove { lock (asyncEventLock) asyncEvent -= value; }
}
protected void OnSyncEvent(SyncEventArgs e)
{
SyncEventHandler handler;
lock (syncEventLock) handler = syncEvent;
if (handler != null) handler(this, e, null, null); // Blocks and locks
//if (handler != null) handler.BeginInvoke(this, e, null, null); // Neither blocks nor locks
}
protected void OnAsyncEvent(AsyncEventArgs e)
{
AsyncEventHandler handler;
lock (asyncEventLock) handler = asyncEvent;
//if (handler != null) handler(this, e, null, null); // Blocks and locks
if (handler != null) handler.BeginInvoke(this, e, null, null); // Neither blocks nor locks
}
}
}
[Form]
Imports mySpace
Public Class Form1
Public WithEvents component As New mySpace.myClass()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
component.DoWork("String", 1)
End Sub
Private Sub component_SyncEvent(ByVal sender As Object, ByVal e As pbxapi.SyncEventArgs) Handles component.SyncEvent
MessageBox.Show("Synchronous event", "Raised:", MessageBoxButtons.OK)
End Sub
Private Sub component_AsyncEvent(ByVal sender As Object, ByVal e As pbxapi.AsyncEventArgs) Handles component.AsyncEvent
MessageBox.Show("Asynchronous event", "Raised:", MessageBoxButtons.OK)
End Sub
End Class