异步引发事件 [英] Raising events asynchronously

查看:123
本文介绍了异步引发事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找到这样做的异步事件分派在一个有许多用户到其事件的组件的选项。在仔细阅读的选项,我跑过这个例子:

 公共事件ValueChangedEvent的ValueChanged;
公共无效FireEventAsync(EventArgs的发送)
{
    委托[]代表= ValueChanged.GetInvocationList();
    的foreach(代表d。在代表)
    {
        ValueChangedEvent EV =(ValueChangedEvent)D;
        ev.BeginInvoke(即,NULL,NULL);
    }
}
 

超越旧的语法(使样品从.NET 1.1),它看起来对我来说,这是一种严重的资源泄漏。有没有完成的方法,没有投票完成,或其他任何方式 EndInvoke会将被调用。

我的理解是,每的BeginInvoke 必须的相应 EndInvoke会。否则,正在等待 AsyncResult 对象实例左右浮动,以及在异步事件中提出的(潜在的)异常。

我意识到,这是很容易改变,通过提供一个回调,做一个 EndInvoke会,但如果我不需要。 。

处理异步产生的异常完全是另一回事,而且,再加上需要与UI线程(即 InvokeRequired 等)同步很可能罐整想法做这些异步通知。

于是,两个问题:

  1. 我是正确的相信每一个的BeginInvoke 需要相应的 EndInvoke会
  2. 除了我上面提到的,还有其他缺陷做异步事件通知在Windows窗体应用程序?
解决方案

一个调用的BeginInvoke()应当与配对 EndInvoke会() 但没有这样做会不会导致资源泄漏。该的IAsyncResult 返回的BeginInvoke()将被垃圾收集。

在此code最大的陷阱是你高度接触异常终止应用程序。你可能想换行委托调用一个异常处理程序,并把一些思想到你想怎么传播这种情况发生的异常(报告第一次,产生总异常等)。

调用deletage使用的BeginInvoke()将一个线程关闭线程队列开始运行的事件。这意味着,该事件将永远断火的主UI线程。这可能使一些事件处理的情况很难处理(如更新UI)。处理程序将需要意识到,他们需要调用 SynchronizationContext.Send()。员额()与主同步UI线程。当然,所有其他的多线程编程的陷阱同样适用。

I'm looking into options for doing asynchronous event dispatching in a component that has many subscribers to its events. In perusing the options, I ran across this example:

public event ValueChangedEvent ValueChanged;
public void FireEventAsync(EventArgs e)
{
    Delegate[] delegates = ValueChanged.GetInvocationList();
    foreach (Delegate d in delegates)
    {
        ValueChangedEvent ev = (ValueChangedEvent)d;
        ev.BeginInvoke(e, null, null);
    }
}

Beyond the older syntax (the sample was from .NET 1.1), it looks to me like this is a serious resource leak. There's no completion method, no polling for completion, or any other way that EndInvoke will be called.

My understanding is that every BeginInvoke must have a corresponding EndInvoke. Otherwise there are pending AsyncResult object instances floating around, along with (potentially) exceptions that were raised during the asynchronous events.

I realize that it's easy enough to change that by supplying a callback and doing an EndInvoke, but if I don't need to . . .

Handling the asynchronous exeptions is another matter entirely, and, combined with the need to synchronize with the UI thread (i.e. InvokeRequired, etc.) could very well tank the whole idea of doing these asynchronous notifications.

So, two questions:

  1. Am I correct in believing that every BeginInvoke requires a corresponding EndInvoke?
  2. Beyond what I've noted above, are there other pitfalls to doing asynchronous event notifications in Windows Forms applications?

解决方案

A call to BeginInvoke() should be paired with a EndInvoke() but not doing it will not result in a resource leak. The IAsyncResult returned by BeginInvoke() will be garbage collected.

The biggest pitfall in this code is you are highly exposed to exceptions terminating the application. You might want to wrap the delegate invocation in an exception handler and put some thought into how you want to propagate the exceptions that happen (report the first, produce an aggregate exception, etc).

Invoking a deletage using BeginInvoke() will take a thread off the thread queue to start running the event. This means that the event will always fire off the main UI thread. This might make some event handler scenarios harder to handle (e.g. updating the UI). Handlers would need to realize they need to call SynchronizationContext.Send() or .Post() to synchronize with the primary UI thread. Of course all other multi-thread programming pitfalls also apply.

这篇关于异步引发事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆