如何在c#中使用参数启动线程?
是的:
Thread t = new Thread (new ParameterizedThreadStart(myMethod)); t.Start (myParameterObject);
Thread构造函数的两个重载之一采用ParameterizedThreadStart委托,允许您将单个参数传递给start方法。不幸的是,虽然它只允许一个参数,它这样做的方式是不安全的,因为它传递作为对象。我发现使用lambda表达式捕获相关参数并以强类型的方式传递它们要容易得多。
试试下面的方法
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) { ... }
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" } }
你可以使用ParametrizedThreadStart委托:
string parameter = "Hello world!"; Thread t = new Thread(new ParameterizedThreadStart(MyMethod)); t.Start(parameter);
ParameterizedThreadStart接受一个参数。您可以使用它来发送一个参数或包含多个属性的自定义类。
ParameterizedThreadStart
另一种方法是将想要启动的方法作为实例成员放在类中,并将其与想要设置的参数的属性放在一起。创建类的实例,设置属性并启动指定实例和方法的线程,这样方法就可以访问属性。
Thread thread = new Thread(Work); thread.Start(Parameter); private void Work(object param) { string Parameter = (string)param; }
参数类型必须为对象。
编辑:
虽然这个答案是正确的,但我不建议使用这种方法。使用lambda表达式更容易阅读,并且不需要类型强制转换。看这里:https://stackoverflow.com/a/1195915/52551
你可以使用BackgroundWorker RunWorkerAsync方法并传入你的值。
你可以使用lambda表达式
private void MyMethod(string param1,int param2) { //do stuff } Thread myNewThread = new Thread(() => MyMethod("param1",5)); myNewThread.Start();
这是目前为止我能找到的最好的答案,又快又简单。
我在传递的参数中有问题。 我将一个整数从for循环传递给函数并显示它,但它总是给出不同的结果。(1、2、2、3)(1、2、3、3)(1,1,2,3)与< em > ParametrizedThreadStart < / em >委托等。< / p >
这个简单的代码很有魔力
使用lambda的简单方法是这样的..
Thread t = new Thread(() => DoSomething("param1", "param2")); t.Start();
或你甚至可以使用ThreadStart来delegate,像这样…
ThreadStart
delegate
private void DoSomething(int param1, string param2) { //DO SOMETHING... ThreadStart ts = delegate { if (param1 > 0) DoSomethingElse(param2, "param3"); }; new Thread(ts).Start(); //DO SOMETHING... }
或使用net 4.5 +更干净,像这样..
private void DoSomething(int param1, string param2) { //DO SOMETHING.. void ts() { if (param1 > 0) DoSomethingElse(param2, "param3"); } new Thread(ts).Start(); //DO SOMETHING.. }
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() + " "); } } } }
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` } }
正如在这里的各种回答中已经提到的,Thread类目前(4.7.2)提供了几个带有重载的构造函数和一个Start方法。
Thread
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)如下所示:
Work
private void Work(object data) { ... }
剩下的就是启动线程。这可以通过使用任何一种方式来实现
public void Start();
或
public void Start(object parameter);
虽然Start()将启动线程并将null作为数据传递给方法,但Start(...)可用于将任何东西传递给线程的Work方法。
Start()
null
Start(...)
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方法的数据类型。不幸的是,这样的东西还不存在(目前?)
ParameterizedThreadStart<T>
T
然而,这个问题有一个建议的解决方案。它涉及到创建一个类,其中包含传递给线程的数据以及表示worker方法的方法,如下所示:
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();
因此,通过这种方式,您可以简单地避免强制转换,并以类型安全的方式向线程提供数据;-)
我建议使用__abc0代替Thread;它允许多个参数并且执行得非常好。
下面是一个工作示例:
public static void Main() { List<Task> tasks = new List<Task>(); Console.WriteLine("Awaiting threads to finished..."); string par1 = "foo"; string par2 = "boo"; int par3 = 3; for (int i = 0; i < 1000; i++) { tasks.Add(Task.Run(() => Calculate(par1, par2, par3))); } Task.WaitAll(tasks.ToArray()); Console.WriteLine("All threads finished!"); } static bool Calculate1(string par1, string par2, int par3) { lock(_locker) { //... return true; } } // if need to lock, use this: private static Object _locker = new Object();" static bool Calculate2(string par1, string par2, int par3) { lock(_locker) { //... return true; } }
使用lambda表达式的一种非常简单和方便的方式是这样的:
Thread thread = new Thread( (param) => { string name = param as string; // rest of code goes here. }); thread.Start("MyName");
通过这种方式,lambda表达式可以具有参数并在单独的线程中运行内联代码。