Azure functions 在Azure函数的HttpTrigger中立即返回

Azure functions 在Azure函数的HttpTrigger中立即返回,azure-functions,Azure Functions,我有一个带有HttpTrigger的Azure函数 我想将202 Accepted立即返回给调用方,然后实际处理调用,这大约需要一秒钟 有什么最佳实践方法可以做到这一点吗? 在回电话之前,我不想做任何事情,所以不可能首先调用EventGrid或类似功能 拒绝的选项 调用事件网格 通过调用EventGrid,我可以在EventGrid调用完成后立即返回,并且实际处理可以在订阅该事件的另一个函数中进行。我不想这样,因为调用EventGrid需要很长的时间,而且它有时会失败,或者比正常情况下需要更长的

我有一个带有HttpTrigger的Azure函数

我想将202 Accepted立即返回给调用方,然后实际处理调用,这大约需要一秒钟

有什么最佳实践方法可以做到这一点吗?

在回电话之前,我不想做任何事情,所以不可能首先调用EventGrid或类似功能

拒绝的选项 调用事件网格 通过调用EventGrid,我可以在EventGrid调用完成后立即返回,并且实际处理可以在订阅该事件的另一个函数中进行。我不想这样,因为调用EventGrid需要很长的时间,而且它有时会失败,或者比正常情况下需要更长的时间

添加到队列 通过向队列中添加消息,我可以实现与EventGrid相同的功能,并且它也存在与上述相同的问题

调用不带“wait”的函数 我知道,通过在我的函数中调用一个方法而不等待,它将不会等待响应,我将能够立即返回。然而,我的测试表明,这是高度不可靠的,但请让我知道,如果你认为这是一条路要走,为什么

自定义线程
我可以使用Thread和ThreadStart等手动执行此操作,我想如果需要,我可能会这样做,但我问这个问题是为了寻找更好的解决方案。

这里有一个
FunctionInvocationFilterAttribute
,这可能是您正在寻找的。此属性仍在预览中,但工作正常。通过重写
OnExecutingAsync
方法,您可以创建自己的属性来实现它,并定义执行函数时要执行的操作

诸如此类:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Host;
using System.Threading;
using System.Linq;

namespace FunctionApp
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class ReturnResponseBeforeExecutionAttribute : FunctionInvocationFilterAttribute
    {
        public override Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken)
        {
            var request = executingContext.Arguments.Values.FirstOrDefault(argument => argument is HttpRequest) as HttpRequest;

            request.HttpContext.Response.StatusCode = 202;
            request.HttpContext.Response.Body.Flush();
            request.HttpContext.Response.Body.Close();
            return Task.CompletedTask;
        }
    }

    public class DoStuff
    {
        [ReturnResponseBeforeExecution]
        [FunctionName("DoStuff")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}
使用系统;
使用System.IO;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.Azure.WebJobs;
使用Microsoft.Azure.WebJobs.Extensions.Http;
使用Microsoft.AspNetCore.Http;
使用Microsoft.Extensions.Logging;
使用Newtonsoft.Json;
使用Microsoft.Azure.WebJobs.Host;
使用系统线程;
使用System.Linq;
命名空间函数
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
公共类ReturnResponseBeforExecutionAttribute:FunctionInvocationFilterAttribute
{
公共覆盖任务OneExecutingAsync(函数executingContext executingContext,CancellationToken CancellationToken)
{
var request=executingContext.Arguments.Values.FirstOrDefault(argument=>argument为HttpRequest)作为HttpRequest;
request.HttpContext.Response.StatusCode=202;
request.HttpContext.Response.Body.Flush();
request.HttpContext.Response.Body.Close();
返回Task.CompletedTask;
}
}
公开课
{
[ReturnResponseBeforExecution]
[函数名(“DoStuff”)]
公共异步任务运行(
[HttpTrigger(AuthorizationLevel.Function,“get”,“post”,Route=null)]HttpRequest请求,
ILogger日志)
{
LogInformation(“C#HTTP触发器函数处理了一个请求。”);
字符串名称=请求查询[“名称”];
string requestBody=等待新的StreamReader(req.Body).ReadToEndAsync();
动态数据=JsonConvert.DeserializeObject(requestBody);
名称=名称??数据?.name;
string responseMessage=string.IsNullOrEmpty(名称)
?“此HTTP触发的函数已成功执行。请在查询字符串或请求正文中为个性化响应传递名称。”
:$“您好,{name}。此HTTP触发的函数已成功执行。”;
返回新的OkObjectResult(responseMessage);
}
}
}
编辑:刚刚意识到,在返回响应之前,它仍在等待函数执行。

可以对此提供帮助


您可以通过HTTP启动编排,该编排将返回客户端可以轮询的状态URL。

这看起来是一个令人惊讶的解决方案,但可惜它没有起作用。而不是
返回任务。CompletedTask
您可以使用
返回Task.FromException(newunauthorizedAccessException())。这将中止函数执行。实际上,您可以将其与任何异常类型一起返回。持久函数是否实际添加到表存储或后台队列中以完成此操作?是的,它确实如此。我猜它会带来与添加到队列一样的轻微性能损失。我的意思是,对于我所描述的场景来说,这是一个非常好和健壮的解决方案,但本质上,我想你可以说它等同于问题中描述的EventGrid和Queue选项?我认为它确实相当于同一件事,尽管也许你不必编写代码来完成这一点。调用HttpTrigger的频率有多高?我已经用CloudEvents v1.0处理过AEG端点验证的相同情况对ThreadPool.QueueUserWorkerItem中的后台线程使用请求后激发&忘记模式。请注意,此解决方案适用于运行时间很短的后台任务。@RomanKiss很抱歉回复太晚。让我们想象一下它每秒被调用5次。