Skip to main content
 首页 » 编程设计

c#之SemaphoreSlim 和异步/等待

2024年01月26日31zhoujg

这个有效:

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(); 
    } 
} 

在第一次点击之后,其他按钮的点击将被忽略,直到工作完成。 标题可以是1或0。

这行不通

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会上升到2、3等。

我做错了什么?

请您参考如下方法:

async void 仅在事件处理程序中有意义。它是一种特殊类型的异步。它的意思是“发射后忘记”。

您不想触发并忘记 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(); 
    } 
}