gpt4 book ai didi

c# - 如何使 HttpContext 在同步调用的任务中可用?

转载 作者:太空宇宙 更新时间:2023-11-03 23:05:36 26 4
gpt4 key购买 nike

在我的 ASP.NET MVC 应用程序中,我需要实现/覆盖一些内部实体,例如 IModelBinder.BindModel() , IActionFilter.OnActionExecuting()等。这些方法正在调用异步方法,但显然我不能将它们变成 async Task<>能够使用 await关键字。

所以我写了下面的“适配器”:

public static T GetResult<T>(Func<Task<T>> func)
{
var httpContext = HttpContext.Current;

var proxyTask = Task.Run(() =>
{
HttpContext.Current = httpContext;
return func();
});

return proxyTask.Result;
}

这让我调用我的异步 GetData()以同步方式:

public static async Task<Data> GetData()
{
if (isCached)
return GetCachedData();

var data = await GetOriginalData();
SetCachedData(data);
return data;
}

...

var data = GetResult(() => GetData());

好的,它有效,所以我会结束它,但是如您所见,大多数时候,GetData()同步运行,因此无条件生成新线程在性能方面并不好。这让我很烦恼,所以我最终得到了一个不同的解决方案:

public static T GetResult<T>(Func<Task<T>> func)
{
var syncContext = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(null);

var task = func();

SynchronizationContext.SetSynchronizationContext(syncContext);

return task.Result;
}

它也有效,但问题是自 SynchronizationContext不再流入,没有HttpContext在被调用的方法中可用。

我可能可以通过输入 HttpContext.Current 来解决这个问题进入逻辑 CallContext但我仍然想知道是否有更好的方法来解决这个问题?像定制 SynchronizationContext.Current.CreateCopy() .

最佳答案

spawning a new thread unconditionally

其实就是简单的从线程池中借用一个线程。几乎没有开始一个新线程那么糟糕,但仍然不是最好的性能。

It also works, however the issue is that since SynchronizationContext is no longer flowing in, there is no HttpContext available in the called method.

你确定吗?我希望 HttpContext.Current 设置在 GetData 的开头,以便两种方式调用它。我还希望 HttpContext.Currentawait 之后为 null两种方式调用它。如果在您的测试中 await 之后它不是 null,可能是因为延续恰好在同一个线程上结束。

这是尝试在请求上下文 (SynchronizationContext) 之外使用 HttpContext.Current 的主要问题之一。当您将它放在一个裸线程 (Task.Run) 上时,它会一直呆在那里,直到该线程进入另一个请求上下文。

I could probably work that around by putting HttpContext.Current into logical CallContext

我建议在原始请求上下文中从 Current 中提取您需要的任何数据,然后将该数据显式传递给需要它的方法。

关于原始问题(避免同步情况下的额外线程),我建议只添加一个同步 TryGetData 方法。

关于c# - 如何使 HttpContext 在同步调用的任务中可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41331644/

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