C# 如何将一个对象放入另一个线程中?

C# 如何将一个对象放入另一个线程中?,c#,multithreading,C#,Multithreading,在c#中有没有办法将对象放到另一个线程中?我所发现的只是如何在另一个线程中实际执行某些方法。我实际上想做的是在一个新线程中实例化一个对象,以便以后使用它提供的方法 希望你能帮助我, Russo如果在线程中运行的方法驻留在自定义类中,则可以使用该类的成员来保存参数 public class Foo { object parameter1; object parameter2; public void ThreadMethod() { ... } }

在c#中有没有办法将对象放到另一个线程中?我所发现的只是如何在另一个线程中实际执行某些方法。我实际上想做的是在一个新线程中实例化一个对象,以便以后使用它提供的方法

希望你能帮助我,
Russo

如果在线程中运行的方法驻留在自定义类中,则可以使用该类的成员来保存参数

public class Foo
{
   object parameter1;
   object parameter2;

   public void ThreadMethod()
   {
       ...
   }
}

对象并不真正属于线程。如果有对对象的引用,则可以从多个线程访问该对象

这可能会导致对象出现问题,这些对象不是设计用于从许多线程访问的,例如(几乎所有)System.Windows.Forms类,以及对COM对象的访问


如果只希望从同一线程访问对象,请在对象(或包装对象)中存储对该线程的引用,并通过该线程执行方法。

进程的所有线程共享相同的数据(忽略线程本地存储),因此无需在线程之间显式迁移对象

internal sealed class Foo
{
    private Object bar = null;

    private void CreateBarOnNewThread()
    {
        var thread = new Thread(this.CreateBar);

        thread.Start();

        // Do other stuff while the new thread
        // creates our bar.
        Console.WriteLine("Doing crazy stuff.");

        // Wait for the other thread to finish.
        thread.Join();

        // Use this.bar here...
    }

    private void CreateBar()
    {
        // Creating a bar takes a long time.
        Thread.Sleep(1000);            

        this.bar = new Object();
    }
}

所有线程都可以看到堆栈heap,因此,如果线程具有对所需对象的引用(例如,通过方法传入),则线程可以使用这些对象。这就是为什么在多线程时访问对象时必须非常小心,因为两个线程可能会同时尝试更改对象


NET中有一个
ThreadLocal
类,可用于将变量限制到特定线程:请参阅和使用
ParameterizedThreadStart
将对象传递到线程。

“供以后使用它提供的方法。”

使用包含在新线程和其他数据和方法上执行的方法的类,您可以从线程访问新线程中的数据和方法

但是。。。如果从类中执行方法,则在当前线程上执行

要在新线程上执行该方法,需要进行一些线程同步

System.Windows.Forms.Control.BeginInvoke执行此操作时,控制线程将等待请求到达


WaitHandle类可以帮助您。

这里似乎对线程的工作方式有一些混淆,因此这是一本入门读物(也很短,所以在深入研究多线程编程之前,您应该找到更多的资料。)

对象和内存本质上是多线程的,因为进程中的所有线程都可以根据自己的选择访问它们

因此,对象与线程没有任何关系

然而,代码在一个线程中执行,而您可能追求的正是代码在其中执行的线程

不幸的是,没有办法仅仅“将一个对象放入另一个线程”,正如您所说的那样,您需要专门启动一个线程并指定在该线程中执行什么代码。因此,该代码使用的对象可以“说”属于该线程,尽管这是您强加给自己的人为限制

因此,没有办法做到这一点:

SomeObject obj = new SomeObject();
obj.PutInThread(thatOtherThread);
obj.Method(); // this now executes in that other thread
事实上,许多新的多线程程序员陷入的一个常见陷阱是,如果他们在一个线程中创建一个对象,并从另一个线程调用该对象上的方法,那么所有这些方法都会在创建该对象的线程中执行。这是不正确的,方法总是在调用它们的线程中执行

因此,以下说法也不正确:

Thread 1:
    SomeObject obj = new SomeObject();

Thread 2:
    obj.Method(); // executes in Thread 1
这里的方法将在线程2中执行。获得在原始线程中执行的方法的唯一方法是与原始线程协作并“要求它”执行该方法。如何做到这一点取决于具体情况,有很多方法可以做到这一点

因此,总结一下您想要的:您想要创建一个新线程,并在该线程中执行代码

要做到这一点,请查看.NET类

但请注意:多线程应用程序很难正确运行,我不会向程序中添加多线程功能,除非:

  • 这是获得更高性能的唯一方法
  • 你知道你在做什么吗

  • 很抱歉重复一些以前的工作,但OP说

    我实际上想做的是在一个新线程中实例化一个对象,以便以后使用它提供的方法

    让我解释为:

    我实际上想做的是让一个新线程实例化一个对象,以便以后我可以使用该对象的方法

    如果我没有注意到,请纠正我。下面是一个例子:

    namespace  silly
    {
        public static class Program
        {
            //declared volatile to make sure the object is in a consistent state
            //between thread usages -- For thread safety.
            public static volatile Object_w_Methods _method_provider = null;
            static void Main(string[] args)
            {
                //right now, _method_provider is null.
                System.Threading.Thread _creator_thread = new System.Threading.Thread(
                    new System.Threading.ThreadStart(Create_Object));
                _creator_thread.Name = "Thread for creation of object";
                _creator_thread.Start();
    
                //here I can do other work while _method_provider is created.
                System.Threading.Thread.Sleep(256);
    
                _creator_thread.Join();
    
                //by now, the other thread has created the _method_provider
                //so we can use his methods in this thread, and any other thread!
    
                System.Console.WriteLine("I got the name!!  It is: `" + 
                    _method_provider.Get_Name(1) + "'");
    
                System.Console.WriteLine("Press any key to exit...");
                System.Console.ReadKey(true);
    
            }
            static void Create_Object()
            {
                System.Threading.Thread.Sleep(512);
                _method_provider = new Object_w_Methods();
            }
        }
        public class Object_w_Methods
        {
            //Synchronize because it will probably be used by multiple threads,
            //even though the current implementation is thread safe.
            [System.Runtime.CompilerServices.MethodImpl( 
                System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
            public string Get_Name(int id)
            {
                switch (id)
                {
                    case 1:
                        return "one is the name";
                    case 2:
                        return "two is the one you want";
                    default:
                        return "supply the correct ID.";
    }}}}
    

    我想详细说明一下前面的答案。为了回到问题所在,对象和内存空间由所有线程共享。所以它们总是共享的,但我假设您希望安全地这样做,并处理由另一个线程创建的结果

    首先尝试一种可信的C#模式。 有一些设置模式可以使用,它们在线程之间传输基本消息和数据。 通常,一个威胁在计算结果后完成

    生命威胁:在异步运行和共享生命威胁数据时,没有什么是万无一失的。 所以,如果你真的需要走这条路,并尝试遵循已知的模式,那么基本上保持它尽可能简单

    现在我想解释一下,为什么一些已知的模式具有某种结构:

    Eventargs:在传递对象之前创建对象的深度副本。(这并不是万无一失的,因为某些引用可能仍然是共享的。) 通过使用int float等基本类型传递结果,可以在构造函数上创建这些类型并使其不可变

    原子关键字一个这些类型,或创建监视器等。。坚持一个线程读取另一个线程写入

    假设您有两个线程上同时处理的复杂数据,我还没有测试过一种完全不同的解决方法: 您可以将结果存储在数据库中,并让其他可执行文件读取它。(行级别上会发生锁,但您可以重试或更改SQL代码,至少会报告死锁。)