繁体   English   中英

如果异步引发事件,是否起作用?

[英]Do events work if raised asynchronously?

我有以下课程的骨架。 如您在TODO:注释中所见,我将在这里实现AsyncEnumerator构造。 该方法将捕获一个请求,并将数据传递给另一个要处理的方法。 基于该过程,我想将事件称为SendMilestoneReached或SendFailed。 我担心由于AsyncEnumerator这些可能会在不同的线程上发生。

这会对将调用Webtext类的UI线程产生影响吗?

/// <summary>
/// Sends Webtexts.
/// </summary>
public class Webtext
{
    #region Event Definitions

    // Events.
    public event EventHandler<SendingEventArgs> SendStarted = delegate { };
    public event EventHandler<SendingEventArgs> SendFailed = delegate { };
    public event EventHandler<SendingEventArgs> SendSuccessful = delegate { };
    public event EventHandler<SendingEventArgs> SendMilestoneReached = delegate { };

    // Shared EventArgs Object, Consumed by the Events.
    SendingEventArgs EventArgs = new SendingEventArgs();

    #endregion

    /// <summary>
    /// Executes the send request.
    /// </summary>
    /// <param name="Operator">The operator whos service to use.</param>
    /// <param name="Username">The username of the requested operator.</param>
    /// <param name="Password">The password of the requested operator.</param>
    /// <param name="Content">The content to send.</param>
    /// <param name="Recipient">The recipient to recieve the content.</param>
    public void ExecuteSendRequest(string Operator, 
                                   string Username, 
                                   string Password, 
                                   string Content, 
                                   string Recipient)
    {
        //TODO: Implement Async requests here.
    }

    #region Event Handlers

    /// <summary>
    /// Called when [sending started].
    /// </summary>
    protected void OnSendingStarted()
    {
        SendStarted(this, EventArgs);
    }

    /// <summary>
    /// Called when [send fail].
    /// </summary>
    protected void OnSendFail()
    {
        SendFailed(this, EventArgs);
    }

    /// <summary>
    /// Called when [send successful].
    /// </summary>
    protected void OnSendSuccessful()
    {

        SendSuccessful(this, EventArgs);
    }

    /// <summary>
    /// Called when [send milestone reached].
    /// </summary>
    protected void OnSendMilestoneReached()
    {
        SendMilestoneReached(this, EventArgs);
    }

    #endregion


}

事件是由引发该事件的同一Thread创建的。 这个原理听起来很简单,但很重要。

所以:

方案1应用已打开。 Webtext由UI线程中的表单初始化,并调用其发送。 Webtext 同步发送请求并触发事件。 在整个过程中,所有操作都在UI线程上完成。

方案2应用已打开。 Webtext由UI线程中的表单初始化,并调用其发送。 Webtext使用辅助线程异步发送请求。 第二线程在事件结束时触发该事件。 这将是工作线程(后台还是前台,具体取决于创建线程的方式)。 通过此线程对UI元素的任何调用都需要使用Invoke完成。

如您所见, 这很大程度上取决于您如何实现send方法。 我看不到发送本身的任何实现,因此,我只能说是生成线程还是使用线程池,它将在工作线程上,否则简单地同步发送将在UI线程上。

请注意,如果您异步引发事件,并且处理程序需要更新用户界面,则它们需要与UI线程同步以便更新任何用户控件。 如果异步引发事件,那么将给订阅事件的类带来更大的负担:它们必须知道如何执行UI线程同步。

对于我来说, 总的来说 ,我发现异步事件是不值得的,因为我几乎总是不得不在UI程序中处理那些事件。 我得出的结论是,如果我要异步处理事件,则处理程序应注意这一点。

这不是一个硬性规定。 绝不是。 例如,默认情况下, System.Timers.Timer在ThreadPool线程上引发事件,但是您可以指定SynchronizingObject以便它可以与UI线程同步。

如果您决定使用异步事件,那么我建议您包括一个诸如Timer的SynchronizingObject之类的工具,以便UI客户端可以使用您的类而不必担心UI线程同步的复杂性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM