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 个附加任务(电子邮件和文档)与显示网页无关,因此如何使用异步修饰符来实现这一点?

或者如果我对异步的理解是错误的......请帮我纠正...

非常感谢。

MVC ASP.NET 中的异步方法

或者如果我对异步的理解是错误的......请帮我纠正...

正如我在博客上解释的那样,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;
    });
}

请注意,additionalDocumentGenerationWork1additionalDocumentGenerationWork2的类型(您在示例中使用了两次相同的名称,因此我在上面更改了它以使代码合法)分别是Documentbool。如果您愿意,可以在第二个任务调用中使用additionalDocumentGenerationWork1(例如,传递第一个操作的结果)。