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

謝謝史蒂芬!在過去幾天的大力幫助。 –