如何回答请求但继续在WebApi中处理代码

rid*_*nsb 9 c# multithreading asynchronous async-await asp.net-web-api

我想回答一个请求,但继续处理代码.

我尝试过类似的东西:

[HttpPost]
public async Task<HttpResponseMessage> SendAsync(MyRequest sms)
{
    await Task.Run(() => Process(sms)); //need to run in a separate thread
    var response = new MyRequest(sms) { Ack = true };
    return Request.CreateResponse(HttpStatusCode.Created, response.ToString());
}

private async void Process(MyRequest sms)
{
    var validationResult = new MyRequestValidation(_p2pContext, _carrierService).Validate(sms);
    if (string.IsNullOrWhiteSpace(validationResult.Errors[0].PropertyName)) // Request not valid
        return;

    Message msg;

    if (validationResult.IsValid)
    {
        msg = await _messageService.ProcessAsync(sms);
    }
    else // Create message as finished
    {
        msg = _messageService.MessageFromMyRequest(sms,
                finished: true,
                withEventSource: validationResult.Errors[0].CustomState.ToString()
              );
    }

    // Salve in db
    _p2pContext.MessageRepository.Create(msg);
    _p2pContext.Save();
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 21

我想回答一个请求,但继续处理代码.

您确定要在ASP.NET中执行此操作吗?这不是ASP.NET(或任何Web服务器)旨在处理的情况.

执行此操作的经典(正确)方法是将工作排入持久队列,并使用单独的后端进程执行该工作的实际处理.

在请求上下文之外的ASP.NET内部进行处理会有各种危险.一般来说,你不能假设工作真的会完成.如果你对此感到满意(或者只是喜欢危险地生活),那么你可以使用HostingEnvironment.QueueBackgroundWorkItem.

我有一篇博文更详细.