0

だから私は呼び出されるいくつかのアクションをキューに入れたいと思います。

少し背景:Webclientを使用してリクエストを送信しようとしましたが、明らかに非常に長いURL(2000文字以上)は許可されておらず、私のシステムでのその値の上限は約40アイテム(正確には43)であることがわかりました。したがって、Webclientリクエストを40〜のセットに分割する必要があり、キューを使用して分割することにしました。

コードは次のとおりです。

  public void some_method()
        int num = 40; // readonly variable declared at top but put here for clarity
        String hash = "";
        Queue<Action> temp_actions = new Queue<Action>();
        foreach (ItemViewModel item in collection)
        {
            num--;
            hash += "&hash=" + item.Hash; // Add &hash + hash to hash

            if (num == 0)
            {
                // Change status for these 40 items
                temp_actions.Enqueue(() => auth.change_status_multiple(status, hash));

                // Reset variables
                num = 40;
                hash = "";
            }
        }

        // Enqueue the last action for the rest of the items
        // Since "num == 0" doesn't cater for leftovers
        // ie. 50 items and 40 in first set, 10 left (which will be enqueued here)
        temp_actions.Enqueue(() => auth.change_status_multiple(status, hash));


        // Start the change status process
        temp_actions.Dequeue().Invoke();

        actions = temp_actions;
    }

    public Queue<Action> actions { get; set; }

    // Event handler for when change_status_multiple fires its event for finish
    private void authentication_MultipleStatusChanged(object sender, EventArgs e)
    {
        if (actions.Count > 0) // Check if there are actions to dequeue
            actions.Dequeue().Invoke();
    }

ただし、ランタイムに関しては、ハッシュは「」になります。たとえば、50個のアイテムがあり、40個がキューに入れられた最初のアクションにあり、次に10個がキューに入れられますが、最初のセットのハッシュ文字列は「」です。何故ですか?アクションをキューにエンキューすると、その時点で指定した変数の値が保持されると思いました。

コードをデバッグし、最初のセットをキューに入れると、ハッシュは正しいのですが、変数numとhashをリセットすると、最初のセット(キュー内)のハッシュが""に変更されます。

とにかくこれの周りにありますか?

ありがとう。

4

2 に答える 2

2

あなたは遅延実行の被害者です...hash次の行でデリゲートのスコープをキャプチャしています:

temp_actions.Enqueue(() => auth.change_status_multiple(status, hash));
//...
hash = "";  //happens before delegate above has executed

その後すぐhashに "" にクリアします。

デリゲートが実行されると、hash既にクリアされています。

修正するには、ローカル コピーを取得しますhash

var hashCopy = hash;
temp_actions.Enqueue(() => auth.change_status_multiple(status, hashCopy));
//...
hash = "";
于 2012-11-26T10:01:47.030 に答える
1

これは、ラムダ式がクロージャstatusを作成し、変数と変数をキャプチャするためhashです。

簡単な解決策は、代わりにキャプチャされる別の変数を作成することです。

string capturedHash = hash;
temp_actions.Enqueue(() => auth.change_status_multiple(status, capturedHash));
于 2012-11-26T10:04:52.807 に答える