准备操作以在另一个线程中使用
本文关键字:线程 另一个 操作 | 更新日期: 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);