Azure Functions 中的孤立异步任务

Posted

技术标签:

【中文标题】Azure Functions 中的孤立异步任务【英文标题】:Orphaned async tasks in Azure Functions 【发布时间】:2021-11-28 11:23:28 【问题描述】:

如果在 Azure 函数中启动了异步任务,但在完成之前孤立会发生什么情况(从不等待),例如:

[Function("FuncAsync")]
public static async Task<HttpResponseData> FuncAsync(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = "FuncAsync")]
    HttpRequestData req,
    FunctionContext context)

    var obj = FactoryClass.GetObject();     // return some object with async LongTaskAsync method
    obj.LongTaskAsync();        // async Task LongTaskAsync()

    return req.CreateResponse(HttpStatusCode.OK);

这里的意图是(我猜)启动一个长时间运行的进程并立即从函数返回。

我认为这是一种不好的做法,但似乎可以在遗留代码中使用。我怀疑该异步任务的生命周期无法保证,并且当没有函数入口点正在运行/触发时,天蓝色进程可能会随机结束。

对于控制台应用程序,如果正在运行的异步任务是孤立的(并在进程终止时继续运行),它将被放弃/杀死(并且不会引发异常)。

    class Program
    
        public static async Task RunFuncAsync()
        
            try
            
                Console.WriteLine("Task started.");
                await Task.Delay(10 * 1000);
                Console.WriteLine("Task finished.");            // this is never executed
            
            catch (Exception e)
            
                Console.WriteLine("Exception: " + e.Message);   // this is never executed
            
        

        static async Task MainAsync(string[] args)
        
            var t = RunFuncAsync();  // no awaiting - purposefuly
            await Task.Delay(5 * 1000);
            Console.WriteLine("Exiting.");
        

        static void Main(string[] args)
        
            MainAsync(args).GetAwaiter().GetResult();
        
    

输出:

Task started.
Exiting.

C:\TestTasks_Console.exe (process 6528) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

【问题讨论】:

【参考方案1】:

如果在 Azure 函数中启动了异步任务但 在完成之前孤立

您对上述问题的回答是正确的,它将被终止。 Azure Functions 具有许多使我们的工作更加轻松的功能。但是,无状态 Azure Functions 不适合需要存储进度状态的长时间运行的操作。

对于这种情况,Durable Functions 是最佳选择。这样,执行时间的限制就不再适用了。

基于任务的编程模型和 async/await 非常适合映射 Durable Functions 的工作流。

如果你检查Azure Function best practices,你也会发现我们应该avoid long running function和我们的function should be stateless

另一种选择是使用 WebJobs。您可以使用 Azure WebJobs 将自定义作业作为 Azure Web 应用程序中的后台任务执行

总之,我们可以说不建议将无状态 Azure Functions 用于长时间运行的操作,因为您可能会遇到超时问题,或者在您的情况下可能会终止。

【讨论】:

以上是关于Azure Functions 中的孤立异步任务的主要内容,如果未能解决你的问题,请参考以下文章

Azure Functions 的 Azure 队列触发器:配置最小轮询间隔

Azure 函数:在异步函数中使用 Apollo Azure 处理程序

使用Azure Functions在Azure blob中运行exe

Azure 函数中的 Az.Functions 模块引发错误

Azure Functions 中的 HttpClient 最佳实践

Azure Functions 中的配置文件