Как синхронизировать задачи?
Скажем, у меня есть метод async, который сохраняет файл:
async Task SaveToFileAsync()
{
var file = await folder.GetFileAsync ( ...)
var stream = file.OpenFileAsync(...)
///etc
}
Теперь представьте, что SaveToFileAsync вызывается дважды одновременно. Это проблема, потому что вы не можете писать в одном и том же файле одновременно
Если бы это был обычный метод, lock() исправил бы это:
void SaveToFile()
{
lock(something)
{
/// code here
}
}
Однако блокировка не допускается в методе async.
Конечно, можно вызвать Monitor.Enter() или использовать мьютекс, но эти объекты работают с потоками, а не с задачами. Поэтому они не являются ответом.
Итак, поскольку lock() не является опцией, как можно синхронизировать несколько задач?
В частности, какой код я должен писать, чтобы гарантировать, что "SaveToFileAsync" вызывается только один раз за раз?
Ответы
Ответ 1
Для механизма асинхронного взаимного исключения посмотрите
Построение примитивов для асинхронной координации, часть 6: AsyncLock
Вы можете использовать класс AsyncLock
:
private readonly AsyncLock m_lock = new AsyncLock();
async Task SaveToFileAsync()
{
using (await m_lock.LockAsync())
{
var file = await folder.GetFileAsync(...);
var stream = await file.OpenFileAsync(...);
// etc
}
}