Reputation: 2453
I have a textbox that accepts input and sends async request to server.
First i typed 'a' and send async request with 'a'. Then i immediately typed 'b' and sends request with 'ab'.
Response for 'ab' is returned faster than response for 'a'. So i ended up getting response for 'a' even though textbox has value 'ab'
I tried with, but it displays last response (which is for 'a')
Task.Run(() => {
// send request
}).ContinueWith((t) => {
// get response
});
I am somewhat newbiew. Can anyone help me how to handle such scenario?
Upvotes: 0
Views: 69
Reputation: 9587
You just need to ensure that the previous request is reliably cancelled when a new one is dispatched. It takes a bit of plumbing, but once you get your head around the pattern it's not difficult:
CancellationTokenSource TextBoxCancellationTokenSource;
async void TextBox_TextChanged()
{
// Harvest values needed to make the request *before* the first await.
string requestArg = TextBox.Text;
if (TextBoxCancellationTokenSource != null)
{
// Cancel previous request.
TextBoxCancellationTokenSource.Cancel();
}
TextBoxCancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = TextBoxCancellationTokenSource.Token;
try
{
// Optional: a bit of throttling reducing the number
// of server requests if the user is typing quickly.
await Task.Delay(100, cancellationToken);
cancellationToken.ThrowIfCancellationRequested(); // Must be checked after every await.
var response = await Task.Run(() => GetResponse(requestArg), cancellationToken);
cancellationToken.ThrowIfCancellationRequested(); // Must be checked after every await.
ProcessResponse(response);
}
catch (OperationCanceledException)
{
// Expected.
}
}
Disclaimer: the above requires that new requests are always queued from a single thread (UI thread most likely).
Upvotes: 2