Мне не пришлось использовать AsyncControllers.
Я использовал фабрику задач, чтобы «запустить и забыть» вызов для начальной загрузки данных при любом вызове контроллера.
Task.Factory.StartNew(() => { var x = GetData(); });
Внутри вызова «GetData» я использовал LOCK, чтобы заставить последующие вызовы ждать, пока не заполнится кэш (адреса # 4)
private static object ThisLock = new object();
protected MyData GetData()
{
if(<MyData in cache>)
return MyData from cache;
lock(ThisLock)
{
// just entered lock, see if cache was set by previous blocking thread
if(MyData in cache>)
return data from cache;
... load MyData from database ...
... save MyData to cache ...
return MyData from cache;
}
}