0

Invoke/BeginInvoke を学習しようとすると、その問題で遭遇しました。

       // Update UI
       public void UpdateForm(string value) {
        txtLog.AppendText(value + "\r\n");
       }


       // Thread function
       private void readSocket() {
        string row = "";

        while (socket.Connected) {                
            row = socket.readLine();            

            if (IsControlValid(this))
                BeginInvoke((MethodInvoker)delegate { UpdateForm(String.Copy(row)); });                    

        }
    }

Invokeメソッドを使用すると UI が正しいテキストで更新されますが、代わりにBegineInvokeを使用すると間違ったテキストが表示されます。つまり、一部のテキストが何度も繰り返し表示されます。私はその電話を知っています

BeginInvoke((MethodInvoker)delegate { UpdateForm(row); });  

おそらく「行」は、共有変数ではなく、共有変数のような動作になる可能性があります

BeginInvoke((MethodInvoker)delegate { UpdateForm(String.Copy(row)); });                    

各 BeginInvoke 呼び出しは「新しい」デリゲートを作成すると思うので、String.Copy を使用すると文字列の別のインスタンスを作成する必要がありますが、常に間違った値 (重複、ecc) が表示されます。

どこが間違っていますか?

4

1 に答える 1

6

おそらく「行」は、共有変数ではなく、共有変数のような動作になる可能性があります

はい、row変数はキャプチャされます。したがって、変数が読み取られるたびに、読み取られるのは最新の値です。ループに変数宣言を配置する必要があります。

while (socket.Connected) {                
    string row = socket.readLine();

    if (IsControlValid(this)) {
        // Removed String.Copy call, as it was pointless
        BeginInvoke((MethodInvoker)delegate { UpdateForm(row); });
    }
}

これで、ループの反復ごとに異なる変数が作成されるため、デリゲートで値を読み取っているときに、1 つのスレッドで以前の値を上書きすることはありません。

于 2013-09-26T18:19:40.323 に答える