gpt4 book ai didi

asp.net-web-api - 我应该在 DelegatingHandler 中的 ReadAsAsync 之后使用 ContinueWith()

转载 作者:行者123 更新时间:2023-12-01 12:46:05 25 4
gpt4 key购买 nike

假设我有一个用于记录 api 请求的 DelegatingHandler。我想访问请求和响应内容以便保存到数据库。

我可以直接使用:

var requestBody = request.Content.ReadAsStringAsync().Result;

我在很多例子中都看到了这一点。也建议使用here似乎知道他们在说什么的人。顺便说一句,之所以提出这个建议,是因为发帖人最初使用的是 ContinueWith,但遇到间歇性问题。

在其他地方,here ,作者明确表示不要这样做,因为它会导致死锁,并建议改用 ContinueWith。此信息显然直接来自 ASP.net 团队。

所以我有点困惑。这 2 个场景在我看来非常相似,因此看起来很矛盾。

我应该使用哪个?

最佳答案

你应该使用await

Result 的一个问题是 it can cause deadlocks ,正如我在我的博客上所描述的那样。

ConfigureAwait 的问题在于,默认情况下它将在 HTTP 请求上下文之外的线程池上执行延续。

您可以使用这些方法中的任何一种来获得可行的解决方案(尽管正如 Youssef 指出的那样,Result 的性能仍然不理想),但何必呢? await 为您完成这一切:无死锁、最佳线程和在 HTTP 请求上下文中恢复。

var requestBody = await request.Content.ReadAsStringAsync();

针对 .NET 4.0 进行编辑:首先,我强烈建议升级到 .NET 4.5。 ASP.NET 运行时在 .NET 4.5 中得到增强,可以正确处理基于 Taskasync 操作。因此,如果您将 WebAPI 安装到 .NET 4.0 项目中,下面的代码可能会或可能不会工作。

就是说,如果您想正确地尝试使用老派的 ContinueWith,像这样的方法应该可行:

protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
var tcs = new TaskCompletionSource<HttpResponseMessage>();
HttpResponseMessage ret;

try
{
... // logic before you need the context
}
catch (Exception ex)
{
tcs.TrySetException(ex);
return tcs.Task;
}

request.Content.ReadAsStringAsync().ContinueWith(t =>
{
if (t.Exception != null)
{
tcs.TrySetException(t.Exception.InnerException);
return;
}

var content = t.Result;
try
{
... // logic after you have the context
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
tcs.TrySetResult(ret);
}, context);
return tcs.Task;
}

现在很清楚为什么 await 好得多了......

关于asp.net-web-api - 我应该在 DelegatingHandler 中的 ReadAsAsync 之后使用 ContinueWith(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15817594/

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