gpt4 book ai didi

c# - 通过事件参数的异步事件处理程序回调

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

当我需要收集已通过包含异步调用的事件 hadler 更改的事件参数数据时,我遇到了问题。正如您在下面的代码中看到的,MessageReceiver 引发事件并从属性“Change”收集数据,然后继续处理。问题是事件处理程序是异步的,因为它使用“等待”调用任何方法。在方法 OnMyEvent 中,代码在调用处理程序后立即继续,它不会等待处理程序完成,因此未设置“更改”属性...如何使事情更“同步”?

public class MyEventArgs:EventArgs
{
public bool Change { get; set; }
}

public delegate void MyEventHandler(object sender, MyEventArgs e);

public class MessageReceiver
{
public event MyEventHandler MyEvent;

public void RaiseEvent()
{
OnMyEvent();
}

protected void OnMyEvent()
{
MyEventArgs e = new MyEventArgs();
if (MyEvent != null)
MyEvent(this, e);
if (e.Change)
Console.WriteLine("Change occured");
}
}
public class Form
{
MessageReceiver mr;
public Form(MessageReceiver MR)
{
mr = MR;
mr.MyEvent += Mr_MyEvent;
}

private async void Mr_MyEvent(object sender, MyEventArgs e)
{
string s = await GetString();
e.Change = true;
}

public async Task<string> GetString()
{
return await Task.Factory.StartNew(() =>
{
return Guid.NewGuid().ToString();
}
);
}
}
public class Program
{
static void Main(string[] args)
{
MessageReceiver mr = new MessageReceiver();
Form frm = new Form(mr);
mr.RaiseEvent();
}
}

最佳答案

我讨论 a variety of approaches for asynchronous events在我的博客上。我推荐延迟方法,您可以使用 DeferralManager 来实现它和 IDeferralSource来 self 的 Nito.AsyncEx.Coordination library 的类型:

public class MyEventArgs: EventArgs, IDeferralSource
{
private readonly DeferralManager _deferralManager;
public MyEventArgs(DeferralManager deferralManager)
{
_deferralManager = deferralManager;
}
public bool Change { get; set; }
public IDisposable GetDeferral() { return _deferralManager.GetDeferral(); }
}

public class MessageReceiver
{
protected async Task OnMyEventAsync()
{
if (MyEvent != null)
{
DeferralManager deferralManager = new DeferralManager();
MyEventArgs e = new MyEventArgs(deferralManager);
MyEvent(this, e);
await deferralManager.WaitForDeferralsAsync();
}
if (e.Change)
Console.WriteLine("Change occured");
}
}

public class Form
{
private async void Mr_MyEvent(object sender, MyEventArgs e)
{
using (e.GetDeferral())
{
string s = await GetString();
e.Change = true;
}
}
}

关于c# - 通过事件参数的异步事件处理程序回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36661687/

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