2013-06-08 5 views
5

У меня есть метод, который часто вызывается из нескольких потоков. Это связано с записью на диск с использованием await FileIO.WriteTextAsync. Это хорошо работает, когда она вызывается из одного потока, но как только я начинаю делать это в нескольких потоках, я получаю эту ошибку:Metro App FileIO.WriteTextAsync Несколько потоков

The process cannot access the file because it is being used by another process. 

Я знаю, что означает, что ошибка, но я не знаю, как работать вокруг него. Обычно я создавал бы оператор lock(object), чтобы гарантировать, что к файлу обращаются только по одному потоку за раз. Однако это асинхронный метод, и поэтому я не могу использовать оператор await в теле оператора lock(object).

Просьба сообщить, как справиться с этим сценарием.

ответ

6

Вы можете использовать SemaphoreSlim действовать как async -соместимым замок:

SemaphoreSlim _mutex = new SemaphoreSlim(1); 

async Task MyMethodAsync() 
{ 
    await _mutex.WaitAsync(); 
    try 
    { 
    ... 
    } 
    finally 
    { 
    _mutex.Release(); 
    } 
} 

Лично мне не нравится finally, так что я обычно пишу мои собственные IDisposable освободить мьютекс при их удалении, и мой код может выглядеть так:

async Task MyMethodAsync() 
{ 
    // LockAsync is an extension method returning my custom IDisposable 
    using (await _mutex.LockAsync()) 
    { 
    ... 
    } 
} 
+0

Ну, Стивен, неудивительно, почему у вас такая огромная репутация. Решение и ваше личное отношение к нему было фантастическим. Теперь мой процесс работает отлично. Я также использовал ваше предложение, чтобы усилить мой класс регистрации, который страдал от подобной проблемы. Спасибо за это! – c0D3l0g1c

+0

Добро пожаловать! –

Смежные вопросы