Task.Run有时会返回两次

时间:2018-12-18 22:37:57

标签: c# asynchronous async-await azure-functions slack

我有一个azure函数应用程序,可以通过一个斜杠命令调用它。 有时,该函数需要一些时间才能返回所请求的数据,因此我使该函数立即返回“正在计算...”消息以松弛,然后在Task.Run上运行实际处理(请求包含我发布的Webhook回到我最终获得数据的时间):

Task.Run(() => opsData.GenerateQuoteCheckMessage(incomingData, context.FunctionAppDirectory, log));

这通常可以很好地工作,除了时不时地人们从松弛状态调用函数时,它将两次返回数据。因此它将显示一个“正在计算...”消息,然后从上述函数返回2个结果。

顺便说一句,Azure功能以: 公共静态异步任务

谢谢!

UPDATE:这是该函数的代码:

    [FunctionName("QuoteCheck")]
     public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequestMessage req, TraceWriter log, ExecutionContext context)
     {
          var opsHelper = new OpsHelper();

          string bodyContent = await req.Content.ReadAsStringAsync();
          var parsedBody = HttpUtility.ParseQueryString(bodyContent);
          var commandName = parsedBody["command"];
          var incomingBrandId = parsedBody["text"];
          int.TryParse(incomingBrandId, out var brandId);
          var responseUrl = parsedBody["response_url"];

          var incomingData = new IncomingSlackRequestModel
          {
               UserName = parsedBody["user_name"],
               ChannelName = parsedBody["channel_name"],
               CommandName = commandName,
               ResponseUri = new Uri(responseUrl),
               BrandId = brandId
          };

          var opsData = OpsDataFactory.GetOpsData(context.FunctionAppDirectory, environment);

          Task.Run(() => opsData.GenerateQuoteCheckMessage(incomingData, context.FunctionAppDirectory, log));

          // Generate a "Calculating" response message based on the correct parameters being passed
          var calculatingMessage = opsHelper.GenerateCalculatingMessage(incomingData);

          // Return calculating message
          return req.CreateResponse(HttpStatusCode.OK, calculatingMessage, JsonMediaTypeFormatter.DefaultMediaType);
      }
 }

然后,GenerateQuoteCheckMessage计算一些数据并最终回发到松弛状态(使用Rest Sharp):

    var client = new RestClient(responseUri);
    var request = new RestRequest(Method.POST);
    request.AddParameter("application/json; charset=utf-8", JsonConvert.SerializeObject(outgoingMessage), ParameterType.RequestBody);

    client.Execute(request);

1 个答案:

答案 0 :(得分:1)

利用Kzrystof的建议,我在发布到队列的函数中添加了一个服务总线调用,并添加了另一个读取队列并处理请求的函数,以响应松弛给我的webhook:

public void DeferProcessingToServiceBus(IncomingSlackRequestModel incomingSlackRequestModel)
{
    var serializedModel = JsonConvert.SerializeObject(incomingSlackRequestModel);
    var sbConnectionString = ConfigurationManager.AppSettings.Get("SERVICE_BUS_CONNECTION_STRING");
    var sbQueueName = ConfigurationManager.AppSettings.Get("OpsNotificationsQueueName");
    var client = QueueClient.CreateFromConnectionString(sbConnectionString, sbQueueName);
    var brokeredMessage = new BrokeredMessage(serializedModel);
    client.Send(brokeredMessage);
}