gpt4 book ai didi

c# - 将异步等待集成到同步方法中

转载 作者:行者123 更新时间:2023-11-30 18:45:31 25 4
gpt4 key购买 nike

这两天我一直在用头撞墙,坦率地说,我对自己很恼火,因为我似乎无法明白

我在 webapi 上下文中。在此请求期间,我需要向我们的其他系统之一发送一些数据,由于计算量大和多个数据库保存等原因,该系统返回速度很慢。我需要记录此操作的结果,无论它是否成功或不。但我不想等待它完成。

我已经 read我应该从上到下一直async await。如果我决定这样做,我将不得不转换许多方法,因为我已经深入研究了 3 或 4 个方法,我担心会扩展更多。

我在这里有哪些选择?如果我一直异步等待,我该如何处理堆栈上层的方法,比如我的 WebApi Controller ?

这是我的代码,我尽可能地精简了它。现在我在 PushResult() 方法中使用 Task.Result()。据我了解,哪个阻止了异步?此代码的工作原理是请求已发送。但是 TestLog 总是最后一个,而不是第一个。因此不是异步的。

    //I'm in a public service and referenced twice
private void MyEndProcess()
{
// other stuff

_vendorPushService.PushResult(); // This could take a while and I have to wait for it!

_logService.PostLog(LogType.TestLog, "Test");
}

//I'm referenced above and somewhere else in the code base
public void PushResult()
{
ExternalResultModel externalResultModel = _resultService.GetExternalResultModel();

PushedResultModel pushedResult = new PushedResultModel();

try
{
pushedResult = _vendorRequestService.PushResultAsync(externalResultModel).Result;
}
catch (Exception ex)
{
pushedResult.Success = false;
}

if (pushedResult.Success)
{
_logService.PostLog(LogType.SuccessLog, pushedResult.Message);
}
else
{
_logService.PostLog(LogType.FailedLog, pushedResult.Message);
}
}

public async Task<PushedResultModel> PushResultAsync(ExternalResultModel externalResultModel)
{
// setup the requestMessage
HttpResponseMessage responseMessage = await _httpRequestService
.SendRequest(requestMessage)
.ConfigureAwait(false);

return new PushedResultModel
{
Success = responseMessage.IsSuccessStatusCode,
Message = await responseMessage.Content.ReadAsStringAsync()
};
}

public class HttpRequestService : IHttpRequestService
{
private readonly HttpClient _httpClient;

public HttpRequestService(IHttpClientAccessor httpClientAccessor)
{
_httpClient = httpClientAccessor.HttpClient;
}

public async Task<HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage)
{
HttpResponseMessage httpResponseMessage = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);

return httpResponseMessage;
}
}

最佳答案

您应该自上而下地实现异步等待。

If I go async await all the way down, what do I do with the methods higher up the stack, like my WebApi controllers?

只需像这样使您的 Controller 操作异步:

[RoutePrefix("api")]
public class PresidentsController : ApiController
{
[Route("presidents")]
public async Task<IHttpActionResult> GetPresidents()
{
await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);
return Ok();
}
}

这是实现异步方法的最简单方法。即使它会添加一些工作来将所有内容更改为异步,它也会在未来受益,因为您将避免异步代码的许多问题。

如果您绝对必须在同步方法中使用异步方法,请将其阻塞在一个地方,如下所示:

public void MySyncMethod()
{
try
{
this.MyAsyncMethod().Wait();

}
catch (Exception exception)
{
//omited
}
}
private async Task MyAsyncMethod()
{
await AsyncLogic().ConfigureAwait(false);
}

但我不推荐它。您应该一直使用 async await 来执行 Controller 操作。

关于c# - 将异步等待集成到同步方法中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47774992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com