[英]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.