2016-10-25 186 views
0

這工作:SemaphoreSlim和異步/等待

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}"; 
} 

點擊按鈕繼續將上升至Tittle23,等等。

我在做什麼錯?

回答

5

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