Ho uno scenario in cui ho un'applicazione per Windows Store, c'è una pagina con una funzionalità di ricerca, l'utente digita i nomi in una casella di testo e l'app cerca nomi simili al testo digitato.
La ricerca viene effettuata tramite la chiamata a un metodo GET AEST RESTful. la chiamata impiega circa 4 secondi per recuperare i risultati. Questo usa la tecnica c # async / await.
Quello che voglio fare è chiamare il metodo HTTP mentre l'utente digita, ma voglio farlo annullando qualsiasi attività in esecuzione e assicurandomi che venga eseguita una sola attività alla volta per evitare di inondare il server con richieste.
Ho implementato il seguente approccio, funziona bene, ma credo che ci possa essere una soluzione migliore:
- Conservo un riferimento all'attività asincrona e a una sorgente di token di annullamento.
-
Mentre l'utente digita, controllo se c'è un'attività in esecuzione, la annullo e ne avvio una nuova con il testo di ricerca più recente.
private CancellationTokenSource cts = null; private Task<List<string>> searchTask; private async void textbox_TextChanged(object sender, TextChangedEventArgs e) { //there is already running task if (searchTask != null && !searchTask.IsCompleted) { //cancel the running and start a new one cts.Cancel(); cts = new CancellationTokenSource(); searchTask=SearchWeb(txtbox.Text, cts.Token); searchTask.ContinueWith(t =>{ //show results }); } else { //start a new one searchTask = dataRepository.SearchUsers(txtbox.Text, cts.Token); searchTask.ContinueWith(t =>{ //show results }); } }
La mia preoccupazione principale è che non mi piace l'overhead generato con il monitoraggio delle attività in esecuzione. Sembra che ci dovrebbe essere un modo più efficiente di fare ciò che non richiede la cancellazione di così tante richieste.