准备操作以在另一个线程中使用

本文关键字:线程 另一个 操作 | 更新日期: 2023-09-27 18:33:51

我想定义一个操作,该操作使用值设置属性(由工作线程计算)。应在另一个线程上下文(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");
    }

为什么这给我"空"而不是"萨米"?

准备操作以在另一个线程中使用

Person 类型是一个结构体。这意味着当您将person作为参数传递时,会创建一个副本。因此,该操作会更新副本,而不是person本身。如果将Person更改为类,您将看到您的示例有效。

有关结构和类之间区别的详细信息,请参阅 .Net 中的结构和类之间有什么区别?

为了证明@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 的副本。名称设置为"Sami"的 Person 对象与您用于写入名称的 Person 对象不同。

您使用的线程和操作是错误的。 通过创建一个线程(设置一个操作来设置人员的姓名),您实际上没有做任何特别的事情。

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