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