我有使用中间件像这样的请求管道设置自定义执行上下文的WebAPI:如何在ASP .NET Core请求管道中仍然有未完成的子线程时停止线程重用?
public async Task Invoke(HttpContext httpContext)
{
using (Context.With(new TokenContext("token")))
{
await _next(httpContext);
}
}
和上下文管理器看起来有点像这样与IContext
对象是本地的一叠当前线程(以及它创建的线程)。
public static class Context
{
private static AsyncLocal<Stack<IContext>> _current = new AsyncLocal<Stack<IContext>>();
public static IContext Current
{
get
{
return _current.Value != null && _current.Value.Count > 0 ?_current.Value.Peek() : null;
}
}
public static IDisposable With(IContext context)
{
Assert.IsNotNull(context);
if (_current.Value == null) _current.Value = new Stack<IContext>();
_current.Value.Push(context);
return new DelegateDisposable(() =>
{
_current.Value.Pop();
});
}
}
我遇到的问题是当有多个请求在同一时间进行。有时我遇到的问题不是我所期望的。我注意到在使用using语句设置它之前,当前上下文有时已经有了一个值。我的结论是,用于请求的初始线程在遇到await _next
行时会返回到线程池,并且此线程可以重新用于以下请求,这些请求有时在“子线程”完成之前发生。这给我留下了很多不可预知的行为。
所以,我的问题:我该如何调整这个,使我不会遇到这个问题?我可以强制请求管道在所有“子线程”完成之前不返回线程吗?这会效率低下吗?我可以强制“母线程”在它将自身返回到池之前清理它对上下文堆栈的引用吗?
还有其他的选择吗?
谢谢,它的工作! –