gpt4 book ai didi

c# - 如何异步调用事件?

转载 作者:行者123 更新时间:2023-11-30 20:17:16 27 4
gpt4 key购买 nike

我正在构建一个将由其他开发人员使用的控件,并且在一些地方我有开发人员可以订阅的事件来执行一些可能需要很长时间的操作。

我的目标是为他们提供使用异步/等待、多线程、后台 worker 等的选项。如果他们选择,但仍然能够在事件调用完成之前完成执行。这是一个伪代码示例(我意识到这无法编译,但希望意图很明确):

我的代码:

public event MyEventHandler MyEvent;
private void InvokeMyEvent()
{
var args = new MyEventArgs();

// Keep the UI responsive until this returns
await MyEvent?.Invoke(this, args);

// Then show the result
MessageBox.Show(args.Result);
}

开发者/订阅者的潜在代码:

// Option 1: The operation is very quick,
// so the dev doesn't mind doing it synchronously
private void myForm_MyEvent(object sender, MyEventArgs e)
{
// Short operation, I'll just do it right here.
string result = DoQuickOperation();
e.Result = result;
}

// Option 2, The operation is long,
// so the dev wants to do it on another thread and keep the UI responsive.
private void myForm_MyEvent(object sender, MyEventArgs e)
{
myForm.ShowProgressPanel();

// Long operation, I want to multithread this!
Task.Run(() =>
{
string result = DoVeryLongOperation();
e.Result = result;
})
.ContinueWith((task) =>
{
myForm.HideProgressPanel();
}
}

是否有任何标准方法可以实现此目的?我正在查看委托(delegate)的 BeginInvoke 和 EndInvoke 方法,希望它们能有所帮助,但我并没有真正想出任何办法。

如有任何帮助或建议,我们将不胜感激!谢谢!

最佳答案

没有标准的方法可以做到这一点。

当我遇到这种情况时,我个人的偏好是使用返回 Task 的自定义委托(delegate)类型。同步返回的处理程序可以简单地返回 Task.CompletedTask,它们不需要为此创建新任务。

public delegate Task MyAsyncEventHandler(object sender, MyEventArgs e);
public event MyAsyncEventHandler MyEvent;
private async Task InvokeMyEvent()
{
var args = new MyEventArgs();

// Keep the UI responsive until this returns
var myEvent = MyEvent;
if (myEvent != null)
await Task.WhenAll(Array.ConvertAll(
myEvent.GetInvocationList(),
e => ((MyAsyncEventHandler)e).Invoke(this, args)));

// Then show the result
MessageBox.Show(args.Result);
}

注意在局部变量中捕获 myEvent 以避免线程问题,并使用 GetInvocationList() 确保等待所有任务。

请注意,在此实现中,如果您有多个事件处理程序,它们会被同时安排,因此可以并行执行。处理程序需要确保它们不会以线程不安全的方式访问 args

根据您的用例,顺序执行处理程序(循环中的 await)可能更合适。

关于c# - 如何异步调用事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45379046/

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