我有以下方法可以解析返回任务的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();
我收到以下错误:
其他信息:使用LifetimeScope实例是不安全的 跨线程。确保一生的完整操作 范围环绕在同一个线程中执行并确保 LifetimeScope实例与它放在同一个线程上 得到了。使用ManagedThreadId 27在线程上调用Dispose, 但是在ID为21的线程上创建。
我不太确定如何使用using语句在.NET中包装异步任务,尝试使用额外的包装器任务来控制流程。
答案 0 :(得分:6)
您需要使用AsyncScopedLifestyle代替。 ThreadScopedLifestyle
(以前称为LifetimeScopeLifestyle
)创建了一个特定于线程的作用域,而AsyncScopedLifestyle
创建了一个与异步方法的逻辑控制流一起流动的作用域。
// using SimpleInjector.Lifestyles;
using (AsyncScopedLifestyle.BeginScope(container)) {
var service = container.GetInstance<ISomeService>();
// ...
}