异步触发的事件可以在窗体上同步运行吗?

dlr*_*as2 4 .net c# vb.net delegates asynchronous

[VS 2010 Beta与.Net Framework 3.5]

我编写了一个C#组件来异步监视套接字并在收到数据时引发事件.我设置VB表单以在引发事件时显示消息框.我注意到的是,当组件同步引发事件时,消息框会阻止组件代码并锁定表单,直到用户关闭消息.当它异步引发时,它既不会阻塞代码,也不会锁定表单.

我想要的是一种方式来引发一个事件,它不会阻塞代码,但是在与表单相同的线程上调用(这样它就会锁定表单直到用户选择一个选项.)

你能帮我吗?谢谢.

[零件]

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

[形成]

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
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 6

您需要调用表单BeginInvoke方法(仅),它将在表单的UI线程上运行委托(从而阻止表单),而不会阻止调用线程等待调用完成.

如果你没有到窗体实例的引用,您可以节省SynchronizationContext.Current从UI线程,然后调用PostSynchronizationContext情况下,这将是等效的.