I've got the following method which resolves an IConsumeAsync
which returns a task.
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;
}
I need to wrap this with a lifetime scope ala
using(var scope = container.BeginLifetimeScope()){
}
I've tried the following but it did not work 100%
var scope = container.BeginLifetimeScope();
var wrapper = ConsumeMessageAsync<TMessage, TConsumer>(message);
wrapper.ContinueWith(x => scope.Dispose());
wrapper.Start();
And I got the following error:
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.
I'm not quite sure how to wrap an asynchronous task in .NET with using statements to tried a manual kind using an extra wrapper task to control the flow.
You need to use the AsyncScopedLifestyle instead. The ThreadScopedLifestyle
(previously called LifetimeScopeLifestyle
) creates a thread-specific scope, while the AsyncScopedLifestyle
creates a scope that flows with the logical flow of control of asynchronous methods.
// using SimpleInjector.Lifestyles;
using (AsyncScopedLifestyle.BeginScope(container)) {
var service = container.GetInstance<ISomeService>();
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With