c# - Task.Run 有时会返回两次
问题描述
我有一个从斜杠命令调用的天蓝色函数应用程序。有时该函数需要一些时间来返回请求的数据,所以我让该函数返回一个“正在计算...”消息以立即松弛,并在 Task.Run 上运行实际处理(请求包含我发布的 webhook回到我最终得到数据的时候):
Task.Run(() => opsData.GenerateQuoteCheckMessage(incomingData, context.FunctionAppDirectory, log));
这工作得很好,除了人们不时地从 slack 调用函数时,它会返回两次数据。因此它将显示一条“正在计算...”消息,然后从上述函数返回 2 个结果。
顺便说一句,Azure 函数以:public static async Task 开头
谢谢!
更新:这是函数的代码:
[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 计算一些数据并最终发回 slack (Using 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);
解决方案
使用 Kzrystof 的建议,我在发布到队列的函数中添加了一个服务总线调用,并添加了另一个函数来读取该队列并处理请求,响应 slack 给我的 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);
}
推荐阅读
- wpf - 动态附加/分离 WPF 行为是解决我的问题的有效方法吗?
- google-classroom - 无法检查 Google OAuth 同意屏幕验证过程的状态
- flutter - 在 Future 返回结果后设置一个 offer
- sql - 计算名称是否出现在给定日期下
- python - 为什么我们需要在函数中的第二个参数之后初始化参数参数?
- powershell - 有没有办法将凭据传递给点源脚本?
- javascript - React-bootstrap 导航栏图标不服从浮动
- jasper-reports - JasperReport 图像根据页面大小动态垂直拉伸 - 可以吗?
- git - 如何从 GitHub 存储库为另一个项目创建单独的 Intellij 项目?
- css - 为什么使用手机时flex div中宽度为25%的img之间存在一些差距?