异步任务和简单注入器生命周期范围

Mic*_*arr 5 c# multithreading asynchronous inversion-of-control simple-injector

我有以下方法解决了IConsumeAsync返回任务的方法.

private Task ConsumeMessageAsync<TMessage, TConsumer>(TMessage message)
    where TMessage : class
    where TConsumer : IConsumeAsync<TMessage>
{
    var tsc = new TaskCompletionSource<object>();
    var instance = (IConsumeAsync<TMessage>)container
        .GetInstance(typeof(TConsumer));

    instance
        .Consume(message)
        .ContinueWith(task =>
        {
            if (task.IsFaulted && task.Exception != null)
            {
                tsc.SetException(task.Exception);
            }
            else
            {
                tsc.SetResult(null);
            }
        });

    return tsc.Task;
}
Run Code Online (Sandbox Code Playgroud)

我需要用一生的范围ala来包装它

using(var scope = container.BeginLifetimeScope()){
}
Run Code Online (Sandbox Code Playgroud)

我尝试过以下但是没有100%工作

var scope = container.BeginLifetimeScope();

var wrapper = ConsumeMessageAsync<TMessage, TConsumer>(message);
wrapper.ContinueWith(x => scope.Dispose());
wrapper.Start();
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

附加信息:跨线程使用LifetimeScope实例是不安全的.确保生命周期范围内的完整操作在同一个线程中执行,并确保LifetimeScope实例在创建时放置在同一个线程上.使用ManagedThreadId 27在线程上调用Dispose,但是在ID为21的线程上创建了Dispose.

我不太确定如何在.NET中使用语句来包装异步任务,尝试使用额外的包装器任务来控制流程.

Ste*_*ven 6

您需要使用AsyncScopedLifestyle.的ThreadScopedLifestyle(以前称为LifetimeScopeLifestyle)创建了一个线程特定范围,而AsyncScopedLifestyle可创建与异步方法控制的逻辑流流动的范围.

// using SimpleInjector.Lifestyles;

using (AsyncScopedLifestyle.BeginScope(container)) {
    var service = container.GetInstance<ISomeService>();
    // ...
}
Run Code Online (Sandbox Code Playgroud)