Can an asynchronously fired event run synchronously on a form?

Posted by cyclotis04 on Stack Overflow See other posts from Stack Overflow or by cyclotis04
Published on 2010-05-17T16:26:33Z Indexed on 2010/05/17 16:30 UTC
Read the original article Hit count: 208

Filed under:
|
|

[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

© Stack Overflow or respective owner

Related posts about c#

Related posts about asynchronous