C# 通过事件参数的异步事件处理程序回调
当我需要收集通过包含异步调用的事件hadnler更改的事件参数数据时,我遇到了一个问题。正如您在下面的代码中看到的,MessageReceiver引发事件并从属性“Change”收集数据,然后继续处理。问题在于事件处理程序是异步的,因为它调用带有“wait”的asny方法。在方法OnMyEvent中,代码在调用处理程序后立即继续,它不会等待处理程序完成,因此不会设置“Change”属性。。。如何使事情更加“同步”C# 通过事件参数的异步事件处理程序回调,c#,events,asynchronous,C#,Events,Asynchronous,当我需要收集通过包含异步调用的事件hadnler更改的事件参数数据时,我遇到了一个问题。正如您在下面的代码中看到的,MessageReceiver引发事件并从属性“Change”收集数据,然后继续处理。问题在于事件处理程序是异步的,因为它调用带有“wait”的asny方法。在方法OnMyEvent中,代码在调用处理程序后立即继续,它不会等待处理程序完成,因此不会设置“Change”属性。。。如何使事情更加“同步” 公共类MyEventArgs:EventArgs { 公共布尔更改{get;set
公共类MyEventArgs:EventArgs
{
公共布尔更改{get;set;}
}
公共委托void MyEventHandler(对象发送方,MyEventArgs e);
公共类消息接收器
{
公共活动MyEventHandler MyEvent;
公共无效RaiseEvent()
{
OnMyEvent();
}
受保护的无效OnMyEvent()
{
MyEventArgs e=新的MyEventArgs();
if(MyEvent!=null)
MyEvent(this,e);
如果(如变更)
Console.WriteLine(“发生了更改”);
}
}
公开课表格
{
消息接收者mr;
公共表格(MessageReceiver MR)
{
mr=mr;
mr.MyEvent+=mr_MyEvent;
}
私有异步void Mr_MyEvent(对象发送方,MyEventArgs e)
{
字符串s=等待GetString();
e、 改变=正确;
}
公共异步任务GetString()
{
return wait Task.Factory.StartNew(()=>
{
返回Guid.NewGuid().ToString();
}
);
}
}
公共课程
{
静态void Main(字符串[]参数)
{
MessageReceiver mr=新MessageReceiver();
表格frm=新表格(mr);
RaiseEvent先生();
}
}
我在博客上讨论。我建议采用延迟方法,您可以使用my中的和类型来实现该方法:
因为我正在编写一个处理程序,所以我可以设法从异步方法GetString获得如下结果:private void Mr_MyEvent(object sender,MyEventArgs e){string s=GetString().result;e.Change=true;}但是如果其他人编写了一个处理程序呢?如何等待事件处理程序在方法“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();
}
}
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;
}
}
}