MVC ASP.NET 中的异步方法
本文关键字:异步方法 NET ASP MVC | 更新日期: 2023-09-27 18:30:21
我想创建一个异步方法,该方法将打开一个线程并完成几个与当前http请求相对独立的任务(例如,发送电子邮件和生成文件,这两者都需要时间)
我创建了以下方法
private static async Task<T> DoSeparateTask<T>(Func<T> func)
{
return func();
}
并希望以这样的方式使用它:
private static void DoSomething()
{
#step 1 - some code for immediate processing
#step 2 - some code for generating documents which takes time
var additionalDocumentGenerationWork = DoSeparateTask<Document>(() =>{
#additional code for generating Document
#even though it returns Document, but 99% time it wont be used in this method
});
#step 3 - some code for sending SMTP email which takes time
var additionalDocumentGenerationWork = DoSeparateTask<bool>(() =>{
#additional code for sending email
return true;
});
}
一切都编译了,但是当我运行 Web 应用程序时,它仍然会不断加载并等待所有内容完成,然后再渲染网页。 由于 2 个附加任务(电子邮件和文档)与显示网页无关,因此如何使用异步修饰符来实现这一点?
或者如果我对异步的理解是错误的......请帮我纠正...
非常感谢。
或者如果我对异步的理解是错误的......请帮我纠正...
正如我在博客上解释的那样,async
不会改变HTTP协议。归根结底,每个请求只有一个响应。换句话说,async
让位于线程池,而不是客户端。
您正在寻找一种在请求/响应生命周期之外执行操作的方法,ASP.NET 不直接支持这种方法。我在我的博客上描述了一些方法。最佳(最可靠)方法是将工作放入队列中,并具有处理队列的独立后端(例如 Azure 辅助角色)。
您不需要 DoSeparateTask<T>()
方法。相反,只需使用 Task.Run<T>()
:
private static async Task DoSomething()
{
// #step 1 - some code for immediate processing
// #step 2 - some code for generating documents which takes time
var additionalDocumentGenerationWork1 = await Task.Run(() =>
{
// #additional code for generating Document
// #even though it returns Document, but 99% time it wont be used in this method
});
// #step 3 - some code for sending SMTP email which takes time
var additionalDocumentGenerationWork2 = await Task.Run(() =>
{
// #additional code for sending email
return true;
});
}
请注意,additionalDocumentGenerationWork1
和additionalDocumentGenerationWork2
的类型(您在示例中使用了两次相同的名称,因此我在上面更改了它以使代码合法)分别是Document
和bool
。如果您愿意,可以在第二个任务调用中使用additionalDocumentGenerationWork1
(例如,传递第一个操作的结果)。