gpt4 book ai didi

c# - 异步触发的事件可以在表单上同步运行吗?

转载 作者:太空狗 更新时间:2023-10-30 00:46:35 24 4
gpt4 key购买 nike

[VS 2010 Beta with .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
}
}
}

[表格]

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

最佳答案

您需要调用 formBeginInvoke 方法(仅),该方法将在窗体的 UI 线程上运行委托(delegate)(从而阻塞窗体),而不会阻塞调用线程等待调用完成。

如果您没有对表单实例的引用,您可以从 UI 线程保存 SynchronizationContext.Current,然后在 SynchronizationContext 上调用 Post 实例,这将是等效的。

关于c# - 异步触发的事件可以在表单上同步运行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2850834/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com