我有一个webform,我使用TPL在后台发送电子邮件,因为我们的SMTP服务器速度很慢,许多用户最终都无法摆脱提交按钮。在过去,我曾使用过System.Threading
和静态方法来完成,这是一个类似任务 - 在.NET3.5,我的代码是这样的:关于在ASP.NET 4.0中使用任务并行库的说明
Thread t = new Thread(new ParameterizedThreadStart(SendEmail));
t.Start(txtEmail.Text);
凡SendEmail的签名是public static void AddEmailToMailingListInBackground(object EmailString)
和我所记得的方法必须是静态的,并且我必须将TextBox txtEmail的值传递给异步方法,否则可能会失去对控件值的访问权限,因为页面生命周期是独立进行的。
现在使用System.Threading.Tasks
当我的代码如下所示:
Task.Factory.StartNew(() => SendEmail(), TaskCreationOptions.LongRunning);
和SendEmail的签名是private void SendEmail()
和我直接内的方法来访问的txtEmail
的Text
财产。
我在这里看到两个主要区别。首先,我的异步方法不再必须是静态的。其次,如果我使用线程,那么在页面的生命周期完成之后很长时间内,我就可以访问该方法中页面的控件值。这两点让我相信,在所有任务完成或页面生命周期完成之前,页面一直保持活动状态,以先到者为准。我已经通过调试并通过异步方法进行了测试 - 响应被发送到浏览器,但我仍然能够浏览并访问控件及其值。 This MSDN article有一点帮助,但仍然没有真正巩固我对TPL与执行异步调用之前的.NET4方式发生的事情的理解。
任何人都可以告诉我,如果我的思想是正确的,这是在使用TPL和ASP.NET时的可靠行为?
有人会关心进一步阐述吗?
感谢德鲁,特别是关于异常处理的警告。一些要求澄清。 1)在将try/catch块中的SendMail调用封装到SendMail中的行为与try/catch块中的SendMail的主体封装相比,在使用OnlyOnFaulted选项的延续方面有什么区别?我做了一些阅读,发现当捕获方法外部时,你应该寻找一个AggregateException [我认为] – joelmdev 2012-02-23 14:49:18
@ jm2是的,那是真的。直接在SendMail任务中直接使用try/catch就可以直接使用同步代码,所以异常将像vanilla .NET代码一样传播。如果您使用ContinuationApproach,则执行SendMail任务时发生的任何异常都将由AggregateException包装。如果你知道你的SendMail在下面是完全同步的,那么如果你需要检查它并对不同类型作出反应,你可以轻松/安全地从AggregateException :: InnerException属性中取出原始异常。 – 2012-02-23 16:46:40
由于评论被破坏,部分内容部分2)您是否说直接访问值是不安全的,因为它们可能会发生变化?控制和它们的值是可用的我假设由于SynchronizationContext维护/恢复页面状态。 – joelmdev 2012-02-23 18:41:59