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