Reputation: 14412
I'm putting together a simple C# app where a user types commands into a "command bar" and the results are fetched in real time.
For example I could type, google stackoverflow
, and it sends an API call off to google, fetches each of the results and displays them in the ui.
Currently I fire off the "search" method if a user pauses for more than 1/4 of a second on typing, so if you paused in the middle it could fire google stack
and google stackoverflow
.
Now in reality the api is doing a (rather slow) database query and this causes the ui to lock up while the first search completes, before it tries to start on the second search.
Is there a simple (C# 4.0) way to run the search call in a separate thread that I can then cancel/abort if the user continues typing?
e.g.
Task<string> thread;
string getSearchResults(string input) {
... Do some work ...
}
string userPaused(string search) {
if(this.thread.isRunning()) this.thread.Kill();
this.thread = new Task<String>(getSearchResults(string input);
return this.thread.result();
}
I've looked at the Tasks api and it doesn't look as if you can kill a task in the middle of work, it suggests using a while look and passing a shouldStop
boolean, however during an API call to download the results there is no while loop.
The Threading documentation however points you to tasks if you need to get the return value.
Upvotes: 0
Views: 191
Reputation: 3379
What you may do with Tasks
is to create them, and then cancel when not needed any more. If you can't cancel operation you are doing (like database query) - you can always cancel before results get returned. Your code may be something like this (not tested, just a draft):
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() =>
{
ct.ThrowIfCancellationRequested();
var result = Database.GetResult(); // whatever database query method you use.
ct.ThrowIfCancellationRequested();
return result;
}, tokenSource2.Token);
So as you can see it will query database and return value when no cancellation requested, but if you will try to cancell the task - it will not return value but rather throw OperationCanceledException
you need to catch. For details visit MSDN Task Cancellation, but I think this should give you an idea. Don't worry about big task number - if your query is not very slow it won't matter - user will not be able to trigger so many searches. If you have asynchronous way of querying database - you can improve this code a bit more, but that also shouldn't be too hard.
Upvotes: 1