Мне интересно, было бы уместно использовать класс TaskCompletionSource
в следующем примере:
Исходный код/без TaskCompletionSource
public async Task GetData()
{
if (!IsLoaded)
{
MyList = await Mediator.Send(new GetData());
IsLoaded = true;
}
}
Эта функция доступна как часть одноэлементной службы в моем веб-приложении .NET Core. Несколько объектов могут использовать записи в MyList
и будут ожидать функции GetData()
перед использованием списка.
Из примера функции видно, что метод может вызываться несколько раз, в то время как первый вызов все еще ожидает результата запроса посредника. Мне нужно решение, позволяющее нескольким объектам ожидать одну и ту же задачу. Так уместно ли использовать объект TaskCompletionSource
для этой цели?
Рефакторинг с использованием TaskCompletionSource
private TaskCompletionSource getDataTask;
public async Task VerifyDataIsLoaded()
{
if (getDataTask == null)
{
getDataTask = new TaskCompletionSource();
Task.Factory.StartNew(async () =>
{
await GetData();
getDataTask.TrySetResult();
}
}
return getDataTask.Task;
}
private async Task GetData()
{
MyList = await Mediator.Send(new GetData());
}
Это должно привести к тому, что первый вызов VerifyDataIsLoaded()
создаст экземпляр объекта TaskCompletionSource getDataTask
, запустит функцию GetData()
в новой многопоточной задаче и вернет свойство getDataTask.Task
.
Теперь, если какие-либо другие объекты вызывают VerifyDataIsLoaded()
, пока функция GetData()
ожидает возврата от объекта Mediator
, все они будут ожидать одну и ту же задачу и предотвратят любые избыточные вызовы GetData
.
Мысли?? ... плохая идея?? лучший способ??
GetData
не сработает? Потому что вы вызываете огонь и забываете моду, поэтому, если она потерпит неудачу, вы никогда не узнаете, иgetDataTask
никогда не завершится. - person Peter Csala   schedule 21.07.2021