Yeasin Abedin
Yeasin Abedin

Reputation: 2453

async response for two different calls with TPL

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

Answers (1)

Kirill Shlenskiy
Kirill Shlenskiy

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

Related Questions