views:

211

answers:

9

Hey folks,

is there any way in c# to put objects in another thread? All I found is how to actually execute some methods in another thread. What I actually want to do is to instanciate an object in a new thread for later use of the methods it provides.

Hope you can help me, Russo

A: 

If the method that you run in a thread resides in a custom class you can have members of this class to hold the parameters.

public class Foo
{
   object parameter1;
   object parameter2;

   public void ThreadMethod()
   {
       ...
   }
}
Itay
I'd like to know why you were downvoted. Your method is clean and easy to understand. The main thread will have access to the newly created objects via the object that the thread started in. At the same time your thread can create objects without interfering with other threads.
diadem
I'de like to know that either :)
Itay
I think this solution is too naive. Objects don't belong to threads. Objects are entities living of their own. IMO, if need a class like Foo, there are design errors.
onof
+12  A: 

Objects do not really belong to a thread. If you have a reference to an object, you can access it from many threads.

This can give problems with object that are not designed to be accessed from many threads, like (almost all) System.Windows.Forms classes, and access to COM objects.

If you only want to access an object from the same thread, store a reference to the thread in the object (or a wrapping object), and execute the methods via that thread.

GvS
+8  A: 

All threads of a process share the same data (ignoring thread local storage) so there is no need to explicitly migrate objects between threads.

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();
    }
}
Daniel Brückner
+2  A: 

All threads can see the stack (correction all threads can see the HEAP!) -- so if the thread has a reference to the objects you need (passed in through a method, for example) then the thread can use those objects. This is why you have to be very careful accessing objects when multi-threading as two threads might try and change the object at the same time.

There is a ThreadLocal<T> class in .NET that you can use to restrict variables to a specific thread: see http://msdn.microsoft.com/en-us/library/dd642243.aspx and http://www.c-sharpcorner.com/UploadFile/ddoedens/UseThreadLocals11212005053901AM/UseThreadLocals.aspx

Dr Herbie
"All threads can see the stack" : no... each thread can see its *own* stack. But all threads can see the heap, however.
Thomas Levesque
My mistake. Confusing heap and stack -- what a beginner's mistake! :(
Dr Herbie
A: 

Don't make your thread method static.

jgauffin
A: 

Use ParameterizedThreadStart to pass an object to your thread.

codymanix
A: 

"for later use of the methods it provides."

Using a class that contains method to execute on new thread and other data and methods, you can gain access from your thread to Data and methods from the new thread.

But ... if your execute a method from the class, you are executing on current thread.

To execute the method on the new thread needs some Thread syncronization.

System.Windows.Forms.Control.BeginInvoke do it, the Control thread is waiting until a request arrives.

WaitHandle class can help you.

x77
+2  A: 

There seem to be some confusion as to how threads work here, so this is a primer (very short too, so you should find more material before venturing forth into multi-threaded programming.)

Objects and memory is inherently multi-thread in the sense that all threads in a process can access them as they choose.

So objects does not have anything to do with threads.

However, code executes in a thread, and it is the thread the code executes in that you're probably after.

Unfortunately there is no way to just "put an object into a different thread" as you put it, you need to specifically start a thread and specify what code to execute in that thread. Objects used by that code can thus be "said" to belong to that thread, though that is an artificial limit you impose yourself.

So there is no way to do this:

SomeObject obj = new SomeObject();
obj.PutInThread(thatOtherThread);
obj.Method(); // this now executes in that other thread

In fact, a common trap many new multi-thread programmers fall into is that if they create an object in one thread, and call methods on it from another thread, all those methods execute in the thread that created the object. This is incorrect, methods always executes in the thread that called them.

So the following is also incorrect:

Thread 1:
    SomeObject obj = new SomeObject();

Thread 2:
    obj.Method(); // executes in Thread 1

The method here will execute in Thread 2. The only way to get the method to execute in the original thread is to cooperate with the original thread and "ask it" to execute that method. How you do that depends on the situation and there's many many ways to do this.

So to summarize what you want: You want to create a new thread, and execute code in that thread.

To do that, look at the Thread class of .NET.

But be warned: Multi-threaded applications are exceedingly hard to get correct, I would not add multi-threaded capabilities to a program unless:

  1. That is the only way to get more performance out of it
  2. And, you know what you're doing
Lasse V. Karlsen
A: 

Sorry to duplicate some previous work, but the OP said

What I actually want to do is to instanciate an object in a new thread for later use of the methods it provides.

Let me interpret that as:

What I actually want to do is have a new thread instantiate an object so that later I can use that object's methods.

Pray correct me if I've missed the mark. Here's the example:

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.";
}}}}
Limited Atonement