Как начать поток с параметрами в С#?
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();
Ответ 7
Используйте ParameterizedThreadStart.
Ответ 8
Используйте ParametrizedThreadStart
.
Ответ 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);
Ответ 12
Вы можете использовать BackgroundWorker метод RunWorkerAsync и передайте свое значение.
Ответ 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() + " ");
}
}
}
}