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

C# 通过事件参数的异步事件处理程序回调,c#,events,asynchronous,C#,Events,Asynchronous,当我需要收集通过包含异步调用的事件hadnler更改的事件参数数据时,我遇到了一个问题。正如您在下面的代码中看到的,MessageReceiver引发事件并从属性“Change”收集数据,然后继续处理。问题在于事件处理程序是异步的,因为它调用带有“wait”的asny方法。在方法OnMyEvent中,代码在调用处理程序后立即继续,它不会等待处理程序完成,因此不会设置“Change”属性。。。如何使事情更加“同步” 公共类MyEventArgs:EventArgs { 公共布尔更改{get;set

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

公共类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;
    }
  }
}