c# - Task cancelling for an autocomplete field doesn't cancel all previous tasks -
i have search method returns search suggestions ui. method fired every time user enters new character search box.
i have added cancellation code cancel previous search request. works not time.
private cancellationtokensource cancellationtokensource; private async task usersearch(string searchcriteria) { debug.writeline("searching {0}....", searchcriteria); try { var cts = new cancellationtokensource(); this.suggestions = await this.searchasync(searchcriteria, cts.token); } catch (operationcanceledexception) { debug.writeline("search({0}) cancelled", searchcriteria); } } private async task<ilist<string>> searchasync(string searchcriteria, cancellationtoken canceltoken) { cancellationtokensource previouscts = this.cancellationtokensource; cancellationtokensource linkedcts = cancellationtokensource.createlinkedtokensource(canceltoken); this.cancellationtokensource = linkedcts; // if previous task running cancel if (previouscts != null) { previouscts.cancel(); } linkedcts.token.throwifcancellationrequested(); list<string> results = (await this.searchprovider.searchasync(searchcriteria, linkedcts.token)).tolist(); debug.writeline("search({0}) returned {1} records", searchcriteria, results.count); linkedcts.dispose(); this.cancellationtokensource = null; return results; }
for example. following debug messages:
searchterm changing to: di searching di.... searchterm changing to: dia searching dia.... search(di) cancelled searchterm changing to: diap searching diap.... search(diap) returned 323 records search(dia) returned 3230 records
as can see first search gets cancelled second 1 doesn't , gets returned after last search giving incorrect results user.
how can ensure previous tasks cancelled?
i think complicating solution little. need see if there existing operation in progress hasn't been cancelled , cancel it. perform new search. untested, think should it.
private cancellationtokensource cancellationtokensource; private async task usersearch(string searchcriteria) { debug.writeline("searching {0}....", searchcriteria); try { if(cancellationtokensource != null && !cancellationtokensource.iscancellationrequested) { cancellationtokensource.cancel(); } cancellationtokensource = new cancellationtokensource(); this.suggestions = await this.searchprovider.searchasync(searchcriteria, linkedcts.token); debug.writeline("search({0}) returned {1} records", searchcriteria, results.count); } catch (operationcanceledexception) { debug.writeline("search({0}) cancelled", searchcriteria); } }
Comments
Post a Comment