C#, Net 5: Асинхронный метод и статик класс, неопределённое поведение
Есть поисковик. Для него я кэширую некоторую информацию в статик класс:
[ApiController]
[Route("api/")]
public class SomeController : ControllerBase
{
private readonly DataRepo _dataRepo;
public SomeController (DataRepo dataRepo)
{
_dataRepo = dataRepo;
}
// вызывается при разворачивании в Azure
[HttpPost]
[Route("[controller]/[action]")]
public void MakeCache() => LocalCache.MakeCache(_dataRepo);
}
public static class LocalCache
{
private static List<DataItemDb> _data = new List<DataItemDb >();
private static bool _dataIsUpdated = false;
public static void MakeCache(DataRepo dataRepo)
{
_data = // получаем инфу из репо, как-то обрабатываем, сеттаем
_dataIsUpdated = true;
}
public static bool DataIsUpdated { get { return _dataIsUpdated ; } }
public static DataItemDb GetItem(string item) => _data.FirstOrDefault(e => e.Item== item);
}
Во время, пока выполняется кэширование, поиск недоступен:
[ApiController]
[Route("api/[controller]")]
public class SearchController : ControllerBase
{
[HttpPost("[action]")]
public async Task<SearchResponse> Search([FromBody] SearchRequest model)
{
Console.WriteLine("Просто так");
if (!LocalCache.DataIsUpdated)
return new SearchResponse(ResponseStateEnum.RetryWith, "Повторите позже");
return DoSearch(model);
}
}
Разворачиваю, вызывается метод кэширования, успешно отрабатывает. Выполняю поиск и... иногда всё идёт нормально, иногда выскакивает "Повторите позже". При этом, при успешном поиске сообщение в логе ("Просто так" которое) появляется, при "Повторите позже" - нет.
Пробовал ставить lock на if (!LocalCache.DataIsUpdated), внутри самого геттера. Толку ноль. Если LocalCache сделать нестатик классом и пробрасывать через DI - тоже самое. Но стоит сделать метод синхронным - всё работает. На локалке проблем нет, только в развёрнутом приложении. Помогите, пожалуйста :(