У меня есть следующие службы WCF:Использование кэшируются Autofac IComponentContext после завершения запроса в WCF
public class TimeService : ITimeService
{
private FooFactory _fooFactory;
public TimeService(FooFactory fooFactory)
{
_fooFactory = fooFactory;
}
public DateTime Now()
{
Foo result = null;
Stopwatch sw = new Stopwatch();
sw.Start();
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] BEGIN Operation");
Task.Run<Foo>(() =>
{
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] BEGIN Task {sw.ElapsedMilliseconds}ms");
Task.Delay(TimeSpan.FromSeconds(10)).Wait();
return _fooFactory.Create();
}).ContinueWith(x =>
{
try
{
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] CONTINUE Task {sw.ElapsedMilliseconds}ms");
result = x.Result;
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] CONTINUE Task {sw.ElapsedMilliseconds}ms, Result = {result}");
}
catch (Exception ex)
{
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] CONTINUE Task {ex}");
}
});
Debug.Print($"[{Thread.CurrentThread.ManagedThreadId}] END Operation {sw.ElapsedMilliseconds}ms");
return result?.Now ?? DateTime.MinValue;
}
}
И это:
public class FooFactory
{
private IComponentContext _componentContext;
public FooFactory(Owned<IComponentContext> componentContext)
{
_componentContext = componentContext.Value;
}
public Foo Create()
{
return _componentContext.Resolve<Foo>();
}
}
Регистрация выглядит следующим образом:
AutofacHostFactory.Container = CreateContainer();
...
private IContainer CreateContainer()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo>().AsSelf();
builder.RegisterType<FooFactory>().AsSelf().InstancePerLifetimeScope();
//builder.Register(c => new FooFactory(c.Resolve<IComponentContext>()));
builder.RegisterType<TimeService>().As<ITimeService>().AsSelf();
return builder.Build();
}
В основном , У меня есть операция, которая сразу возвращается к вызывающему, а задача, которую я запускаю, продолжается в фоновом режиме. Удивительно, но это не прекратило задачу, когда запрос «завершился» - я бы подумал, что так будет.
FooFactory должен динамически создавать Foo, и поэтому он зависит от IComponentContext (или ILifetimeScope - есть ли разница?). Когда я беру зависимость от IComponentContext напрямую или с помощью делегата, как в коде с комментариями, возникает исключение, говорящее, что экземпляр IComponentContext удален. Я предполагаю, что это связано с тем, что размещен родительский ILifetimeScope, который был связан с запросом (через Autofac.WCF). Но если я беру зависимость от Owned, исключение не возникает. Таким образом, кажется, что код работает и делает то, что я хочу.
Однако, вопрос в том, является ли это безопасным?
Я имею в виду, что запрос завершается, и ответ возвращается первому пользователю, и после этого возникает разрешение экземпляра из контекста, созданного для запроса. Что касается Autofac, то объем запроса отсутствует. Представьте, что мы были глубоко в гнездовом пространстве, когда пришел вызов FooFactory.
Каковы последствия?