Как я могу предотвратить повторный вход метода asyn c? - PullRequest
2 голосов
/ 22 января 2020

В моей программе есть метод asyn c. Мне нужно, чтобы задание было асинхронным, потому что оно выполняет сетевые запросы, но я не хочу, чтобы оно повторялось. Другими словами, если метод вызывается из кодового блока A, а затем снова из кодового блока B до возвращения первого вызова, я хочу, чтобы второй вызов дождался завершения первого вызова до его запуска.

Если этот метод не был асинхронным c, я мог бы выполнить 1010 * с помощью этой аннотации: [MethodImpl (MethodImplOptions.Synchronized)] * ​​1003 *

Однако компилятор не позволяет аннотации быть прикрепленным к асинхронному c методу.

Что еще я могу сделать?

1 Ответ

6 голосов
/ 22 января 2020

Вы можете использовать SemaphoreSlim, который является блокировкой с методом WaitAsync (и который не против того, чтобы вы выпустили его в другом потоке для тот, на котором вы его приобрели).

private readonly SemaphoreSlim methodLock = new SemaphoreSlim(1, 1);

public async Task SomeMethod()
{
    await methodLock.WaitAsync();
    try
    {
        ...
    }
    finally
    {
        methodLock.Release();
    }
}

Если вы чувствуете себя авантюрным, вы можете написать метод расширения для SemaphoreSlim, позволяющий вам, например:

public async Task SomeMethod()
{
    using (await methodLock.WaitDisposableAsync())
    {
        ...
    }
}

Be осторожно: SemaphoreSlim является не рекурсивным (и не может быть). Это означает, что если ваш метод рекурсивный, он заходит в тупик.

...