在我的程序中,我正在发出请求,并记录了请求和响应。
但是使用ConfigureAwait(false)
可能会丢失我的"logger"
对象的上下文,该对象将请求记录在一个文件中,并将响应记录在另一个文件中。
try
{
logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
serializedResponse = await httpHandler.PostAsync<string>
(tokenParameters.Endpoint, payloadJson, options, cts.Token)
.ConfigureAwait(false);
}
catch (TaskCanceledException)
{
throw new TokenTimeoutException();
}
catch (Exception ex)
{
logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
throw;
}
知道为什么会这样吗?还是要避免这种情况?
通过删除ConfigureAwait(false)
,我可能会遇到超时问题,因此这不是一种选择。
答案 0 :(得分:1)
这是设计使然,因此您必须问自己: “我这样做正确吗?”
有多种方法可以解决该问题。如果您想要可记录的即发即忘异步调用,可以将其包装在这样的调用中。但是请注意,任务可能在不同的上下文中运行,因此您可能无法访问典型的上下文绑定变量,例如当前的HttpContext(以及类似的东西)。
Task.Run(async () =>
{
try
{
logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
serializedResponse = await httpHandler.PostAsync<string>
(tokenParameters.Endpoint, payloadJson, options, cts.Token);
}
catch (TaskCanceledException)
{
throw new TokenTimeoutException();
}
catch (Exception ex)
{
logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
throw;
}
}).ConfigureAwait(false);
async Task DoStuff()
{
try
{
logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
serializedResponse = await httpHandler.PostAsync<string>
(tokenParameters.Endpoint, payloadJson, options, cts.Token);
}
catch (TaskCanceledException)
{
throw new TokenTimeoutException();
}
catch (Exception ex)
{
logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
throw;
}
}
您当前的代码在哪里:
async Task WhereYouAreDoingStuff()
{
DoStuff().ConfigureAwait(false);
}