Как Вы помещаете объект в другой поток?

есть ли какой-либо путь в c# для помещения объектов в другой поток? Все, что я нашел, - то, как на самом деле выполнить некоторые методы в другом потоке. То, что я на самом деле хочу сделать, является к instanciate объектом в новом потоке для более позднего использования методов, которые это предоставляет.

Надежда можно помочь мне, Russo

14
задан Russo 6 July 2010 в 08:09
поделиться

8 ответов

На самом деле объекты не принадлежат потоку. Если у вас есть ссылка на объект, вы можете получить к нему доступ из многих потоков.

Это может вызвать проблемы с объектами, которые не предназначены для доступа из многих потоков, таких как (почти все) классы System.Windows.Forms, и доступ к COM-объектам.

Если вы хотите получить доступ к объекту только из того же потока, сохраните ссылку на поток в объекте (или объекте-оболочке) и выполните методы через этот поток.

25
ответ дан 1 December 2019 в 06:15
поделиться

Похоже, что существует некоторая путаница в том, как работают потоки, так что это учебник (очень короткий, так что вам следует найти больше материала, прежде чем углубляться в многопоточное программирование).

Объекты и память по своей природе многопоточны в том смысле, что все потоки в процессе могут обращаться к ним по своему усмотрению.

Таким образом, объекты не имеют ничего общего с потоками.

Однако код выполняется в потоке, и вам, вероятно, нужен именно поток, в котором выполняется код.

К сожалению, не существует способа просто "поместить объект в другой поток", как вы выразились, вам нужно специально запустить поток и указать, какой код должен выполняться в этом потоке. Таким образом, можно "сказать", что объекты, используемые этим кодом, принадлежат этому потоку, хотя это искусственное ограничение, которое вы сами себе навязываете.

Так что нет никакого способа сделать это:

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. Единственный способ заставить метод выполняться в исходном потоке - это сотрудничать с исходным потоком и "попросить" его выполнить этот метод. Как это сделать, зависит от ситуации, и существует множество способов сделать это.

Итак, подытожим то, что вы хотите: Вы хотите создать новый поток и выполнить код в этом потоке.

Чтобы сделать это, посмотрите на класс Thread в .NET.

Но будьте осторожны: Многопоточные приложения очень трудно сделать правильными, я бы не стал добавлять возможности многопоточности в программу, если только:

  1. Это единственный способ получить от нее больше производительности
  2. И вы знаете, что делаете
16
ответ дан 1 December 2019 в 06:15
поделиться

Все потоки процесса используют одни и те же данные (игнорируя локальное хранилище потока), поэтому нет необходимости явно переносить объекты между потоками.

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();
    }
}
8
ответ дан 1 December 2019 в 06:15
поделиться

Все потоки могут видеть стек кучу , поэтому, если у потока есть ссылка на нужные вам объекты (например, переданная через метод), поток может использовать эти объекты. Вот почему вы должны быть очень осторожны при доступе к объектам при многопоточности, так как два потока могут попытаться изменить объект одновременно.

В .NET есть класс ThreadLocal , который можно использовать для ограничения переменных определенным потоком: см. http://msdn.microsoft.com/en-us/ library / dd642243.aspx и http://www.c-sharpcorner.com/UploadFile/ddoedens/UseThreadLocals11212005053901AM/UseThreadLocals.aspx

2
ответ дан 1 December 2019 в 06:15
поделиться

"для дальнейшего использования методов, которые он предоставляет."

Используя класс, который содержит метод для выполнения в новом потоке и другие данные и методы, вы можете получить доступ из вашего потока к данным и методам из нового потока.

Но ... если вы выполняете метод из класс, который вы выполняете в текущем потоке.

Для выполнения метода в новом потоке требуется некоторая синхронизация потока.

System.Windows.Forms.Control.BeginInvoke сделайте это, поток управления ждет, пока не поступит запрос .

Класс WaitHandle может вам помочь.

0
ответ дан 1 December 2019 в 06:15
поделиться

Если метод, который вы запускаете в потоке, находится в пользовательском классе, вы можете иметь члены этого класса для хранения параметров.

public class Foo
{
   object parameter1;
   object parameter2;

   public void ThreadMethod()
   {
       ...
   }
}
-1
ответ дан 1 December 2019 в 06:15
поделиться

Используйте ParameterizedThreadStart , чтобы передать объект вашему потоку.

1
ответ дан 1 December 2019 в 06:15
поделиться

Извините, что дублирую предыдущую работу, но ОП сказал

Что я на самом деле хочу сделать, так это инстанцировать объект в новом потоке для последующего использования методов, которые он предоставляет.

Позвольте мне интерпретировать это как:

На самом деле я хочу сделать так, чтобы новый поток инстанцировал объект, чтобы позже я мог использовать методы этого объекта.

Пожалуйста, поправьте меня, если я что-то не понял. Вот пример:

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.";
}}}}
0
ответ дан 1 December 2019 в 06:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: