C# 准备在另一个线程中使用的操作
我想定义一个操作,用一个值(由工作线程计算)设置属性。应该在另一个线程上下文(UI线程)中调用该操作 为了简化问题,可以归结为这样一个问题:为什么这段代码不起作用,我必须做些什么才能使它像预期的那样工作:C# 准备在另一个线程中使用的操作,c#,multithreading,properties,action,C#,Multithreading,Properties,Action,我想定义一个操作,用一个值(由工作线程计算)设置属性。应该在另一个线程上下文(UI线程)中调用该操作 为了简化问题,可以归结为这样一个问题:为什么这段代码不起作用,我必须做些什么才能使它像预期的那样工作: public struct Person { public string Name; } Person person; Action<Person> action; public void Update()
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();
新线程(()=>
{
动作=新动作(c=>c.Name=“Me”);
}).Start();
睡眠(1000);
行动(人);
Debug.WriteLine(person.Name??“null”);
}
为什么这会给我“null”而不是“Sami”?类型
Person
是一个结构。这意味着当您将person
作为参数传递时,将生成一个副本。因此,该操作会更新一个副本,而不是人
本身。如果您将Person
更改为一个类,您将看到您的示例是有效的
有关结构和类之间差异的更多信息,请参见以证明@Elianebing的答案:
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;
}
类程序{
个人;
行动;
静态void Main(字符串[]参数){
程序p=新程序();
p、 更新();
Console.ReadLine();
}
公共无效更新(){
person=新的person();
新线程(()=>{
动作=新动作(c=>c.Name=“Sami”);
}).Start();
睡眠(1000);
行动(人);
Console.WriteLine(person.Name??“null”);
}
}
公共阶层人士{
公共字符串名称;
}
因为您将Person声明为一个结构,所以它是一个值类型——这意味着创建了Person的副本。名称设置为“Sami”的Person对象与您用于写入名称的Person对象不同。您使用的线程和操作错误。通过创建一个线程(设置一个操作来设置人的名字),实际上您没有做任何特殊的事情
new Thread(() =>
{
action = new Action<Person>(c => c.Name = "Me");
}).Start();
Thread.Sleep(1000);
新线程(()=>
{
动作=新动作(c=>c.Name=“Me”);
}).Start();
睡眠(1000);
与
action = new Action<Person>(c => c.Name = "Me");
action(person);
action=newaction(c=>c.Name=“Me”);
行动(人);
你想要的是这样的东西:
action = new Action<Person>(c => c.Name = "Me");
new Thread(action).Start();
Thread.Sleep(1000);
action=newaction(c=>c.Name=“Me”);
新线程(action.Start();
睡眠(1000);
struct关键字在java中不存在。这看起来不像java。这绝对是C(我标记的)。这是专门如何从背景线程中设置UI组件项的吗?我在想同样的事情,但是我没有考虑在那里做更正。虽然您确实指出了action和Thread的正确用法,但它无法解决OP的问题,因为Person
是一个结构体哦,我明白了。你完全正确。谢谢大家,你们帮了我大忙!再想一想——在这个例子中,我没有做什么特别的事情,但是线程被认为是工作线程。它可能会计算ui线程之外的内容,我可以在操作的代码中使用它。我想我还需要另一个线程来准备行动。谢谢,这是丢失的链接!