8

Próbuję opóźnić przetwarzanie metody (SubmitQuery() w przykładzie) wywoływanej z zdarzenia klawiatury w WinRT, dopóki nie będzie żadnych dalszych zdarzeń dla czas (w tym przypadku 500 ms).TaskCanceledException podczas wywoływania Task.Delay z odwołaniemTokenem w zdarzeniu klawiatury

Chcę, aby funkcja SubmitQuery() działała tylko wtedy, gdy wydaje mi się, że użytkownik zakończył pisanie.

Korzystając z poniższego kodu, otrzymuję wywołanie System.Threading.Tasks.TaskCanceledException, gdy Task.Delay (500, cancellationToken.Token); jest nazywany. Co ja tu robię źle, proszę?

CancellationTokenSource cancellationToken = new CancellationTokenSource(); 

private async void SearchBox_QueryChanged(SearchBox sender, SearchBoxQueryChangedEventArgs args) 
{ 

     cancellationToken.Cancel(); 
     cancellationToken = new CancellationTokenSource(); 

    await Task.Delay(500, cancellationToken.Token); 

    if (!cancellationToken.IsCancellationRequested) 
    { 
     await ViewModel.SubmitQuery(); 
    } 
} 

Odpowiedz

11

Tego można się spodziewać. Kiedy anulujesz stare Delay, spowoduje to zgłoszenie wyjątku; tak działa anulowanie. Możesz umieścić prosty try/catch wokół Delay, aby uchwycić oczekiwany wyjątek.

Pamiętaj, że jeśli chcesz wykonywać taktyczną logikę, Rx jest bardziej naturalne niż async.

+0

mógłby Pan podać odnośnik do niektórych zasobów, jak Rx jest lepsze dopasowanie do czasu oparte logika – Anupam

+2

@Anupam: To z własnego doświadczenia. –

25

Jeśli dodasz ContinueWith() z pustą akcją, wyjątek nie zostanie zgłoszony.

await Task.Delay(500, cancellationToken.Token).ContinueWith(tsk => { }); 
+4

To niesamowite, dzięki. Zapisuje naprawdę brzydki kod try/catch :) –

+1

Dzięki za to! Bardzo irytujące w debugerze, mimo że zostało złapane. Myślę, że w sytuacjach ".Day" ** oczekujemy ** anulowania tokenu, aby wyjątek nie został nawet podniesiony/złapany, a to naprawiło to doskonale. –

Powiązane problemy