使用"继续"时简单的喷油器"instance is requested outside the context of an active (Async Scoped) scope"



我有一个代码块,它抛出:

使用"异步作用域"生活方式注册,但在活动(异步作用域(作用域的上下文之外请求实例`

  1. 当我将return用于Task时(在较高的卷上,但在较低的处理卷上可以(,会引发以上情况
  2. 然而,当我awaitTask、Simple Injector不抛出时,无论直通请求量如何,它都可以正常工作

与Simple Injector相比,我理解这可能更像是一个以异步为中心的问题,但有什么见解可以解释为什么用await替换return可以解决这个问题?

提前感谢,我很担心;工作";使用CCD_ 7是否潜在地隐藏了一个更大的问题。

背景:

我有下面的循环,由一个工人定义项目(要调度的任务(:

void Loop()
{
while (cancellationToken.IsCancellationRequested == false)
{
item = await this.queue.Reader.ReadAsync(cancellationToken);

await DispatchItemAsync(item, (item, dispatcher) =>
{
return dispatcher
.SendAsync(((ISendItem)item).GetHandler, item.Message, item.CancellationToken)
.ContinueWith(t => item.TaskCompletionSourceWrapper.SetResult(t.Result), TaskContinuationOptions.RunContinuationsAsynchronously);
});
}
}

来自上述循环的DispatchItemAsync如下:

protected override async Task DispatchItemAsync(
IQueueItem item, Func<IQueueItem, IThreadStrategy, Task> dispatchFunc)
{
// cast the passed item from channel queue
var queueItemWithStack = item as IQueueItemWithStack;
using (AsyncScopedLifestyle.BeginScope(this.container))
{
var dispatcher = container.GetInstance<InParallel>();
// the above is an interface of delegates that is used to call functions

// return throws SimpleInjector outside of scope exception (intermittent,
// always for high request volume)
return dispatchFunc(queueItemWithStack, dispatcher);
// using await no exception is thrown
// await dispatchFunc(queueItemWithStack, dispatcher);
}
}

由于InParallel包含由dispatchFunc行调用的函数,以下内容(最终通过链(被调用:

public Task<object> SendAsync(
Func<SendFunction> getHandler,
object request,
CancellationToken cancellationToken = default)
{
return this
.inCaller
.SendAsync(getHandler, request, cancellationToken)
.ContinueWith(t =>
{ 
// snip some code
// the below throws if DispatchItemAsync call us with return
// but is OK if DispatchItemAsync called us with await instead
return t.Result;
});
}

访问t.Result时,上述ContinueWith发生异常:

CommandHandler是使用"异步作用域"生活方式注册的,但该实例是在活动(异步作用域(作用域的上下文之外请求的。请参阅https://simpleinjector.org/scoped有关如何应用生活方式和管理范围的更多信息。

通过而不是等待Task,您正在与主操作并行执行Task。并行意味着代码变成多线程。

这意味着原始CCD_ 15可能会在CCD_。这会导致您遇到异常。但在其他情况下,Scope可能会在执行Task期间被处理掉。这将导致在Task运行时处理对象。这可能会导致奇怪的多线程问题。

这意味着,在您的情况下,您应该绝对等待从dispatchFunc返回的Task

相关内容

最新更新