SemaphoreSlim and async/await

本文关键字:await async and SemaphoreSlim | 更新日期: 2023-09-27 18:15:01

这行得通:

int _counter;
readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
async void Button_Click(object sender, RoutedEventArgs e)
{
    if (_semaphore.Wait(0))
    {
        Title = $"{ ++_counter}";
        await Task.Delay(1000); // simulate work
        Title = $"{ --_counter}";
        _semaphore.Release();
    }
}

在第一次点击以后的按钮点击被忽略,直到工作完成。Tittle可为10

这个不行

void Button_Click(object sender, RoutedEventArgs e)
{
    if (_semaphore.Wait(0))
    {
        Test(); // moving code into separate method
        _semaphore.Release();
    }
}
async void Test()
{
    Title = $"{ ++_counter}";
    await Task.Delay(1000); // simulate work
    Title = $"{ --_counter}";
}

连续点击按钮,Tittle上升到23等。

我做错了什么?

SemaphoreSlim and async/await

async void仅在事件处理程序中有意义。它是一种特殊类型的异步。它的意思是"烧了就忘了"。

您不希望在启动后忘记Test()方法。您需要等待它返回。

Test签名更改为:

// Note that it returns a "Task". A task is an awaitable promise.
async Task Test()
{
   //...
}

然后在事件处理程序中等待它:

async void Button_Click(object sender, RoutedEventArgs e)
{
     if (_semaphore.Wait(0))
     {
        await Test(); // moving code into separate method
        _semaphore.Release();
    }
}