如果在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);
}
这里的意图是(我猜)启动一个长时间运行的进程,并立即从函数返回。
我认为这是一个不好的做法,但似乎在遗留代码中工作。我怀疑没有保证异步任务的生命周期,azure进程可以随机结束,当没有函数入口点正在运行/触发时。
对于控制台应用程序,如果正在运行的异步任务是孤儿(并且在进程终止时保持运行),它将被放弃/杀死(并且没有抛出异常)。
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 . . .
如果在Azure函数中启动了异步任务,会发生什么孤儿之前完成?
以上问题的答案是正确的,它将使终止。Azure Functions有许多功能,使我们的工作更容易。然而,无状态Azure函数不适合需要存储进度状态的长时间运行操作。
-
对于这种情况,持久函数是最好的选择。因此,执行时间的限制不再适用。
-
基于任务的编程模型和async/awi它非常适合于映射持久函数的工作流。
-
如果你检查Azure功能最佳实践,你也会发现我们应该
avoid long running function
和我们的function should be stateless
。 -
另一个选择是进入WebJobs。您可以使用Azure WebJobs在Azure Web应用程序中执行自定义作业作为后台任务
总之,我们可以说无状态Azure函数不推荐用于长时间运行的操作,因为您可能会遇到超时问题,或者在您的情况下可能会被终止。