Как начать поток с параметрами в C #?
c#
multithreading
JL.
источник
источник
Ответы:
Ага :
источник
void MyParamObject(object myUrl){ //do stuff }
должен иметь тип параметраobject
ParameterizedThreadStart
и ясно из текста вопроса, это, вероятно, не так.Одна из двух перегрузок конструктора Thread принимает делегат ParameterizedThreadStart, который позволяет передать единственный параметр методу start. К сожалению, он допускает только один параметр и делает это небезопасным способом, поскольку передает его как объект. Я считаю, что гораздо проще использовать лямбда-выражение для захвата соответствующих параметров и передачи их строго типизированным способом.
Попробуйте следующее
источник
Dim thr As New Thread(Sub() DoStuff(settings))
Вы можете использовать лямбда-выражения
это пока лучший ответ, который я мог найти, это быстро и легко.
источник
Тип параметра должен быть объектом.
РЕДАКТИРОВАТЬ:
Хотя этот ответ не является правильным, я рекомендую против такого подхода. Использование лямбда-выражения намного проще для чтения и не требует приведения типов. Смотрите здесь: https://stackoverflow.com/a/1195915/52551
источник
Parameter
?источник
Простой способ использования лямбда, как это ..
ИЛИ вы могли бы даже
delegate
использовать,ThreadStart
как так ...ИЛИ используя VS 2019 .NET 4.5+ даже чище, как это ..
источник
Использование
ParametrizedThreadStart
.источник
Используйте ParameterizedThreadStart .
источник
Как уже упоминалось в различных ответах здесь,
Thread
класс в настоящее время (4.7.2) предоставляет несколько конструкторов иStart
метод с перегрузками.Эти соответствующие конструкторы для этого вопроса:
и
которые либо принимают
ThreadStart
делегата, либоParameterizedThreadStart
делегата.Соответствующие делегаты выглядят так:
Таким образом, как видно, правильный конструктор, который нужно использовать, - это тот, который принимает
ParameterizedThreadStart
делегат, так что поток, соответствующий некоторому методу, соответствующему указанной сигнатуре делегата, может быть запущен потоком.Простой пример создания экземпляра
Thread
класса:или просто
Сигнатура соответствующего метода (вызываемого
Work
в этом примере) выглядит следующим образом:Осталось только начать тему. Это делается с помощью либо
или
Хотя
Start()
бы запустить поток и передать вnull
качестве данных в метод,Start(...)
может использоваться для передачи чего-либо вWork
метод потока.Однако у этого подхода есть одна большая проблема: все, что передается в
Work
метод, преобразуется в объект. Это означает, что вWork
методе он должен быть снова приведен к исходному типу, как в следующем примере:Кастинг - это то, что вы обычно не хотите делать.
Что если кто-то пропустит что-то еще, что не является строкой? Поскольку вначале это кажется невозможным (поскольку это мой метод, я знаю, что я делаю, или метод частный, как кто-то может быть в состоянии что-либо передать ему? ), Вы можете в конечном итоге получить именно этот случай по разным причинам. , Поскольку некоторые случаи могут не быть проблемой, другие - нет. В таких случаях вы, вероятно, в конечном итоге
InvalidCastException
получите, который вы, вероятно, не заметите, потому что он просто завершает поток.В качестве решения вы ожидаете получить общий
ParameterizedThreadStart
делегат, например,ParameterizedThreadStart<T>
гдеT
будет тип данных, которые вы хотите передать вWork
метод. К сожалению что-то подобное не существует (пока?).Однако есть предложенное решение этой проблемы. Он включает в себя создание класса, который содержит как данные, передаваемые в поток, так и метод, представляющий метод работ, например:
При таком подходе вы начинаете поток так:
Таким образом, вы просто избегаете перебора и имеете безопасный способ предоставления данных потоку ;-)
источник
private static void MyMethod<T>(T myData) { T message = myData; Console.WriteLine($"the thread wrote: {message}"); }
message.Length
невозможно и так далее)if(myData.GetType() == typeof(string)) { var str = ((string)(object)myData).Length; }
. В любом случае, вместо того, чтобы использовать ваш метод многопоточности, я нашел его более удобнымTasks<T>
, как, напримерtasks.Add(Task.Run(() => Calculate(par1, par2, par3)))
, см. Мой ответ ниже ( stackoverflow.com/a/59777250/7586301 )У меня была проблема в переданном параметре. Я передал целое число из цикла for в функцию и отобразил ее, но она всегда давала разные результаты. как (1,2,2,3) (1,2,3,3) (1,1,2,3) и т. д. с делегатом ParametrizedThreadStart .
этот простой код работал как шарм
источник
ParameterizedThreadStart
Принимает один параметр. Вы можете использовать это для отправки одного параметра или пользовательского класса, содержащего несколько свойств.Другой метод - поместить метод, который вы хотите запустить как член экземпляра, в класс вместе со свойствами для параметров, которые вы хотите установить. Создайте экземпляр класса, установите свойства и запустите поток, указав экземпляр и метод, и метод может получить доступ к свойствам.
источник
Вы можете использовать делегат ParametrizedThreadStart :
источник
Вы можете использовать метод BackgroundWorker RunWorkerAsync и передать свое значение.
источник
источник
Я предлагаю использовать
Task<T>
вместоThread
; он допускает несколько параметров и работает очень хорошо.Вот рабочий пример:
источник
источник