4

我有以下方法可解决返回任务的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; 
} 

我需要用一生范围来包装这个ALA

using(var scope = container.BeginLifetimeScope()){ 
} 

我试过以下,但它没有工作100%

var scope = container.BeginLifetimeScope(); 

var wrapper = ConsumeMessageAsync<TMessage, TConsumer>(message); 
wrapper.ContinueWith(x => scope.Dispose()); 
wrapper.Start(); 

而且我得到了以下错误:

Additional information: It is not safe to use a LifetimeScope instance across threads. Make sure the complete operation that the lifetime scope surrounds gets executed within the same thread and make sure that the LifetimeScope instance gets disposed on the same thread as it gets created. Dispose was called on thread with ManagedThreadId 27, but was created on thread with id 21.

我不太相当确保如何在.NET中使用语句来尝试使用额外的包装任务来控制流的手动类型来包装异步任务。

回答

5

您需要改用AsyncScopedLifestyleThreadScopedLifestyle(以前称为LifetimeScopeLifestyle)创建了一个线程特定的作用域,而AsyncScopedLifestyle创建了一个与异步方法的逻辑控制流一起流动的作用域。

// using SimpleInjector.Lifestyles; 

using (AsyncScopedLifestyle.BeginScope(container)) { 
    var service = container.GetInstance<ISomeService>(); 
    // ... 
} 
+0

谢谢史蒂芬!在过去几天的大力帮助。 –