簡體   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