Question

I have a task to fetch content from my server. The problem is, that sometimes a Task overrides the task before, so I get two times the same result.

My Code:

 Task<string> task = Server.GetText();
        string result = await task;
        if (result == "\n")
        {
            .....
        }
        else
        {
            string[] sarray = result.Split('|');

            App.MainList.Add(new etc.Text(sarray[0], sarray[1], sarray[2], sarray[3], sarray[4]));

            App.Number++;
        }

GetText():

public static async Task<string> GetText()
    {
        if (App.Number <= App.Total)
        {
            HttpClient http = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await http.GetAsync(queryuri + "?w=" + App.Number.ToString());
            return await response.Content.ReadAsStringAsync();
        }

        else
        {
            App.Number = 1;
            HttpClient http = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await http.GetAsync(queryuri + "?w=" + App.Number.ToString());
            return await response.Content.ReadAsStringAsync();
        }

    }
Was it helpful?

Solution

I mean with overwritting the old result, that in the end i have to excact entries. How can I solve the problem?

When the first method enters (presumably because of a user button press) you're calling GetText() using await; Let's assume App.Number is 1 when you first do this. Because of the await execution is suspended right there until GetText() returns, but your GUI is not! Let's assume the user presses the same button again. GetText() will again be called and App.Number will still be 1 because the first GetText() hasn't yet returned. Since the query is built based on App.Number then you're obviously going to get two identical results.

When the first GetText() returns you're going to increment App.Number so it's now 2; When the second GetText() returns the App.Number gets implemented once more! You're not only getting the result for App.Number==1 twice, you're going to complitely skip the result for App.Number==2!

Depending on what the meaning of those numbers is, you'd have multiple solutions: Increment App.Number before you call GetText() AND pass the number as a parameter, make the method non-re-entrant, whatever works for you. If for example there's some meaning in the order of the request, then the best option is to disable the button because HTTP requests sent in parallel aren't guaranteed to complete in the order they were started. For example your GetText(2) could easily return before GetText(1); It's also possible that GetText(n) might never return because of some error.

You now know why you're seeing what you're seeing, but I can't suggest a solution because I don't actually know what the correct behavior should be. That's up to you!

OTHER TIPS

This looks like a threading problem. I'm assuming App.Number starts at 1, and App.Total is 4, but I think it'd happen with any value where App.Number <= App.Total.

The initial code is triggered on two different threads, both of which start running Server.GetText(), and hit the if statement, choose the first branch, build the URL and issue the request with w=1. Since this call takes time, and the App.Number increment is after the response comes back, I think that is what is causing your issue.

I think your issue is that you need to update App.Number as soon as you read it to build the URL (plus hold a lock while reading/incrementing it so that you don't still have a race condition).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top