Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 准备在另一个线程中使用的操作_C#_Multithreading_Properties_Action - Fatal编程技术网

C# 准备在另一个线程中使用的操作

C# 准备在另一个线程中使用的操作,c#,multithreading,properties,action,C#,Multithreading,Properties,Action,我想定义一个操作,用一个值(由工作线程计算)设置属性。应该在另一个线程上下文(UI线程)中调用该操作 为了简化问题,可以归结为这样一个问题:为什么这段代码不起作用,我必须做些什么才能使它像预期的那样工作: public struct Person { public string Name; } Person person; Action<Person> action; public void Update()

我想定义一个操作,用一个值(由工作线程计算)设置属性。应该在另一个线程上下文(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();
新线程(()=>
{
动作=新动作(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线程之外的内容,我可以在操作的代码中使用它。我想我还需要另一个线程来准备行动。谢谢,这是丢失的链接!