0

サーバーからコンテンツを取得するタスクがあります。問題は、タスクが前にタスクをオーバーライドすることがあるため、同じ結果が 2 回得られることです。

私のコード:

 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();
        }

    }
4

2 に答える 2

2

つまり、古い結果を上書きするということは、最終的にエントリを抽出する必要があるということです。どうすれば問題を解決できますか?

最初のメソッドが入力されたとき (おそらくユーザーのボタンが押されたため) ;をGetText()使用して呼び出しています。あなたが最初にこれを行うときだとawait仮定しましょう。戻るまで実行が中断されるため、GUI はそうではありません。ユーザーが同じボタンをもう一度押したとします。最初の呼び出しがまだ返されていないため、再び呼び出されます。クエリはに基づいて構築されているため、明らかに 2 つの同一の結果が得られます。App.Number1awaitGetText()GetText()App.Number1GetText()App.Number

最初GetText()に返されたときにインクリメントApp.Numberするので、 now2です。2 番目GetText()が返されると、App.Numberもう一度実装されます。結果を 2 回取得するだけでなく、App.Number==1完全に の結果をスキップすることになりApp.Number==2ます。

これらの数値の意味に応じて、複数の解決策がありApp.Numberます。呼び出す前にインクリメントGetText()し、数値をパラメーターとして渡し、メソッドを再入不可にします。たとえば、リクエストの順序に何らかの意味がある場合、最適なオプションはボタンを無効にすることです。これは、並行して送信された HTTP リクエストが開始された順序で完了することが保証されていないためです。たとえば、GetText(2)前に簡単に戻ることができますGetText(1); GetText(n)なんらかのエラーが原因で返されない可能性もあります。

表示されているものが表示される理由はわかりましたが、正しい動作がどうあるべきか実際にはわからないため、解決策を提案することはできません。それはあなた次第です!

于 2013-10-06T14:12:29.073 に答える
0

これはスレッドの問題のようです。App.Number は 1 から始まり、App.Total は 4 であると想定していますが、App.Number <= App.Total の値で発生すると思います。

最初のコードは 2 つの異なるスレッドでトリガーされ、どちらも Server.GetText() の実行を開始し、if ステートメントをヒットし、最初のブランチを選択し、URL を構築して w=1 でリクエストを発行します。この呼び出しには時間がかかり、 App.Number のインクリメントは応答が戻った後に行われるため、それが問題の原因だと思います。

あなたの問題は、URLを構築するためにApp.Numberを読んだらすぐに更新する必要があることだと思います(さらに、競合状態にならないように、読み取り/インクリメント中にロックを保持します)。

于 2013-10-06T14:32:17.743 に答える