2

プロパティに値を設定するアクションを定義したい(ワーカースレッドによって計算された)。そのアクションは、別のスレッド コンテキスト (UI スレッド) で呼び出す必要があります。

問題を単純化するために、つまり、このコードが機能しない理由と、意図したとおりに機能させるにはどうすればよいかという問題に要約します。

    public struct Person
    {
        public string Name;
    }

    Person person;
    Action<Person> action;

    public void Update()
    {
        person = new Person();

        new Thread(() =>
        {
            action = new Action<Person>(c => c.Name = "Me");
        }).Start();

        Thread.Sleep(1000);
        action(person);

        Debug.WriteLine(person.Name ?? "null");
    }

「Sami」ではなく「null」と表示されるのはなぜですか?

4

3 に答える 3

4

Personは構造体です。これはperson、引数として渡すと、コピーが作成されることを意味します。したがって、アクションはpersonそれ自体ではなく、コピーを更新します。クラスに変更Personすると、例が機能することがわかります。

構造体とクラスの違いの詳細については、.Net の構造体とクラスの違いは何ですか? を参照してください。

于 2012-05-11T19:27:12.987 に答える
1

@ElianEbbingの答えを証明するには:

   class Program {
      Person person;
      Action<Person> action;
      static void Main(string[] args) {
         Program p = new Program();
         p.Update();

         Console.ReadLine();
      }
      public void Update() {
         person = new Person();

         new Thread(() => {
            action = new Action<Person>(c => c.Name = "Sami");
         }).Start();

         Thread.Sleep(1000);
         action(person);

         Console.WriteLine(person.Name ?? "null");
      }
   }

   public class Person {
      public string Name;
   }

Person を構造体として宣言するため、これは値型です。つまり、Person のコピーが作成されます。Name が「Sami」に設定されている Person オブジェクトは、名前の書き込みに使用している Person オブジェクトとは異なります。

于 2012-05-11T19:34:19.997 に答える
1

スレッドとアクションを間違って使用しています。(人物の名前を設定するアクションを設定する) スレッドを作成することによって、事実上、特別なことは何もしていません。

    new Thread(() =>
    {
        action = new Action<Person>(c => c.Name = "Me");
    }).Start();
    Thread.Sleep(1000);

と同じです

action = new Action<Person>(c => c.Name = "Me");
action(person);

あなたが欲しかったのは次のようなものでした:

action = new Action<Person>(c => c.Name = "Me");
new Thread(action).Start();
Thread.Sleep(1000);
于 2012-05-11T19:35:25.120 に答える