У меня есть ситуация, когда у меня есть дерево объектов, созданное специальным factory. Это несколько похоже на контейнер DI, но не совсем.
Создание объектов всегда происходит через конструктор, и объекты неизменяемы.
Некоторые части дерева объектов могут не понадобиться в данном исполнении и должны создаваться лениво. Таким образом, аргумент конструктора должен быть чем-то вроде factory для создания по требованию. Это выглядит как работа для Lazy
.
Однако для создания объектов может потребоваться доступ к медленным ресурсам и, следовательно, всегда асинхронный. (Функция создания объекта factory возвращает Task
.) Это означает, что функция создания для Lazy
должна быть асинхронной, и, следовательно, вводимый тип должен быть Lazy<Task<Foo>>
.
Но я бы предпочел не иметь двойную упаковку. Интересно, можно ли заставить Task
лениться, т.е. Создать Task
, который, как гарантируется, не будет выполняться до тех пор, пока он не будет ожидаться. Насколько я понимаю, Task.Run
или Task.Factory.StartNew
могут запускаться в любое время (например, если поток из пула простаивает), даже если ничего не ждет.
public class SomePart
{
// Factory should create OtherPart immediately, but SlowPart
// creation should not run until and unless someone actually
// awaits the task.
public SomePart(OtherPart eagerPart, Task<SlowPart> lazyPart)
{
EagerPart = eagerPart;
LazyPart = lazyPart;
}
public OtherPart EagerPart {get;}
public Task<SlowPart> LazyPart {get;}
}