ThreadStart с параметрами

Как начать поток с параметрами в С#?

Ответ 1

Да:

Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);

Ответ 2

Одна из двух перегрузок конструктора Thread вызывает делегат ParameterizedThreadStart, который позволяет передать один параметр методу start. К сожалению, хотя он допускает только один параметр и делает это небезопасным способом, поскольку он передает его как объект. Мне гораздо проще использовать лямбда-выражение, чтобы фиксировать соответствующие параметры и передавать их строго типизированным образом.

Попробуйте выполнить

public Thread StartTheThread(SomeType param1, SomeOtherType param2) {
  var t = new Thread(() => RealStart(param1, param2));
  t.Start();
  return t;
}

private static void RealStart(SomeType param1, SomeOtherType param2) {
  ...
}

Ответ 3

Вы можете использовать лямбда-выражения

private void MyMethod(string param1,int param2)
{
  //do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();

это лучший ответ, который я нашел, это быстро и легко.

Ответ 4

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param)
{
    string Parameter = (string)param;
}

Тип параметра должен быть объектом.

EDIT:

Хотя этот ответ неверен, я рекомендую этот подход. Использование выражения лямбда намного легче читать и не требует литья типов. См. Здесь: fooobar.com/questions/33079/...

Ответ 5

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));

        t.Start("My Parameter");
    }

    static void ThreadMethod(object parameter)
    {
        // parameter equals to "My Parameter"
    }
}

Ответ 6

Простой способ использования лямбда, например...

Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();

ИЛИ, вы можете даже delegate использовать ThreadStart, как это...

ThreadStart ts = delegate
{
     bool moreWork = DoWork("param1", "param2", "param3");
     if (moreWork) 
     {
          DoMoreWork("param1", "param2");
     }
};
new Thread(ts).Start();

Ответ 9

У меня возникла проблема в переданном параметре. Я передал целое число из цикла for в функцию и отобразил его, но он всегда выдавал разные результаты. (1,2,2,3) (1,2,3,3) (1,1,2,3) и т.д. с делегатом ParametrizedThreadStart.

этот простой код работал как прелесть

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param) 
{
 string Parameter = (string)param; 
}

Ответ 10

ParameterizedThreadStart принимает один параметр. Вы можете использовать это для отправки одного параметра или настраиваемого класса, содержащего несколько свойств.

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

Ответ 11

Вы можете использовать делегат ParametrizedThreadStart:

string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);

Ответ 13

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {

            int x = 10;
            Thread t1 =new Thread(new ParameterizedThreadStart(order1));
            t1.IsBackground = true;//i can stope 
            t1.Start(x);

            Thread t2=new Thread(order2);
            t2.Priority = ThreadPriority.Highest;
            t2.Start();

            Console.ReadKey();
        }//Main

        static void  order1(object args)
        {
            int x = (int)args;


                for (int i = 0; i < x; i++)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write(i.ToString() + " ");
            }
        }

        static void order2()
        {
            for (int i = 100; i > 0; i--)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(i.ToString() + " ");
            }
        }'enter code here'
    }
}

Ответ 14

Как уже упоминалось в различных ответах здесь, класс Thread настоящее время (4.7.2) предоставляет несколько конструкторов и метод Start с перегрузками.

Этими соответствующими конструкторами для этого вопроса являются:

public Thread(ThreadStart start);

а также

public Thread(ParameterizedThreadStart start);

которые либо принимают делегат ThreadStart либо делегат ParameterizedThreadStart.

Соответствующие делегаты выглядят так:

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);

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

Простой пример для инициализации класса Thread был бы

Thread thread = new Thread(new ParameterizedThreadStart(Work));

или просто

Thread thread = new Thread(Work);

Подпись соответствующего метода (называемая " Work в этом примере") выглядит так:

private void Work(object data)
{
   ...
}

Осталось начать поток. Это делается с помощью

public void Start();

или же

public void Start(object parameter);

В то время как Start() будет запустить поток и передать null, как данные методе Start(...) может быть использована для передачи что - либо в Work метод резьбы.

Однако существует одна большая проблема с этим подходом: все, что передается методу " Work передается в объект. Это означает, что в методе " Work он должен быть снова добавлен к исходному типу, как в следующем примере:

public static void Main(string[] args)
{
    Thread thread = new Thread(Work);

    thread.Start("I've got some text");
    Console.ReadLine();
}

private static void Work(object data)
{
    string message = (string)data; // Wow, this is ugly

    Console.WriteLine($"I, the thread write: {message}");
}



Кастинг - это то, чего вы обычно не хотите делать.

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

В качестве решения вы ожидаете получить общий делегат ParameterizedThreadStart например ParameterizedThreadStart<T> где T будет типом данных, которые вы хотите передать в метод Work. К сожалению, такого типа не существует (пока?).

Тем не менее, предлагается предлагаемое решение этой проблемы. Он включает создание класса, который содержит как данные, передаваемые потоку, так и метод, который представляет рабочий метод следующим образом:

public class ThreadWithState
{
    private string message;

    public ThreadWithState(string message)
    {
        this.message = message;
    }

    public void Work()
    {
        Console.WriteLine($"I, the thread write: {this.message}");
    }
}

При таком подходе вы должны начать поток следующим образом:

ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);

thread.Start();

Таким образом, вы просто избегаете кастинга и имеете видный способ предоставления данных в поток ;-)

Ответ 15

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {

            int x = 10;
            Thread t1 =new Thread(new ParameterizedThreadStart(order1));
            t1.Start(x);

            Thread t2=new Thread(order2);
            t2.Priority = ThreadPriority.Highest;
            t2.Start();

            Console.ReadKey();
        }//Main

        static void  order1(object args)
        {
            int x = (int)args;


            for (int i = 0; i < x; i++)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write(i.ToString() + " ");
            }
        }

        static void order2()
        {
            for (int i = 100; i > 0; i--)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(i.ToString() + " ");
            }
        }
    }
}