C#多线程传递参数的方法:
1.通过构造函数传递
2.使用线程池的QueueUserWorkItem 方法.该方法第二个参数就是 传递的参数
3.最后一种方法使用异步委托来实现参数的传递
/
为了可以生动详细的介绍整个过程,我建立下面的一个.NET类,它也是要用线程启动的方法的载体。类如下所示:
using System; namespace WindowsApplication1 { public class MyClass{ // for method 1 private string _parameter; public MyClass(string parameter){ this._parameter = parameter; } public void MyMethod1(){ if(this._parameter!=null){ // do something Console.Write(this._parameter); } } // for method 2 public MyClass(){} // this method is private,But it can be public or other private void MyMethod2(string parameter){ // do something Console.Write(parameter); } // Because delegate WaitCallback's parameter Type is object // I will convert it to string. public void MyMethod2(object parameter){ this.MyMethod2((string)parameter); } // for method 3 public string MyMethod3(string parameter){ return "参数值为:"+parameter; } // for mutil-parameters passed public string MyMutilParameters(string param1,string param2){ return "参数1和参数2连接结果为:"+param1+param2; } } } |
1、使用构造函数来传递参数
众所周知,我们可以使用一个带参数的构造函数来构造对象,既然这样我们可以利用构造函数先将要使用的参数值传递到对象里面的内部变量上,然后再使用一个无参数的方法来使用这个参数(假装参数)。简单的说就是,在类里面声明一个变量专门用来保存函数需要的参数,函数变成无参的形式。这种方法的最大问题就是破坏了封装性,虽然我们不能直接方法这些变量但是隐患总是存在的(或者说看上去不爽都可以)。下面代码片断给出了如何使用这个方法来传递参数的详细内容,这也是上面提到的4个按钮中的一个按钮(Button1)的Click代码。为了有参数可传我在WinForm全局定义了一个如下的变量:
// This is parameter's value private string myParameter = "ParameterValue/n"; |
按钮事件如下所示:
// passed parameters to thread by construct private void button1_Click(object sender, System.EventArgs e) { MyClass instance = new MyClass(myParameter); new Thread (new ThreadStart(instance.MyMethod1)).Start(); } |
正如上面所说的,我们使用构造函数传递参数到类里面去,然后在使用上面所说的方法启动了一个线程,我们可以在运行该程序后的output窗口中看到MyMethod1的执行结果是(你也可以用一个TextBox或者其他什么东西直接显示在WinForm上):ParameterValue 。看看函数体就知道这个结果是正确的。是不是很简单。
2、使用ThreadPool来实现参数的传递
我们首先可以看看MSDN对ThreadPool是怎么形容的,Provides a pool of threads that can be used to post work items, process asynchronous I/O, wait on behalf of other threads, and process timers.查看它的方法集合其中有一个叫:QueueUserWorkItem 的方法,该类以及该方法的详细信息请参考MSDN相关帮助。这里需要注意的就是QueueUserWorkItem方法的参数,参数WaitCallback是一个委托类型,第二个参数就是该委托实例(用函数实例化以后,也就是一个函数)所需要的参数,是object类型的。详细内容请看下面的代码。
// passed parameter to thread by ThreadPool private void button2_Click(object sender, System.EventArgs e) { MyClass instance = new MyClass(); ThreadPool.QueueUserWorkItem (new WaitCallback (instance.MyMethod2),myParameter); } |
因为QueueUserWorkItem的二个参数是object类型的所以我们要在MyClass里面定义两个MyMethod2的重裁版本,目的就是为了满足该方法的参数。同样我们将参数myParameter传递进去了,运行程序,当我们点击Button2的时候在output窗口中将会出现MyMethod2将myParameter作为参数执行的结果显示出来。
3、接下来是最后一种方法使用异步委托来实现参数的传递
同样,有关委托的详细信息可以参考MSDN,上面说的非常详细。我们这里要使用到BeginInvoke和EndInvoke方法。首先我们给出传递一个参数的方法如下所示:
// passed parameter by asynchronous delegate delegate string MyMethod3Delegate(string parameter); private void button3_Click(object sender, System.EventArgs e) { MyClass instance = new MyClass(); MyMethod3Delegate myMethod3 = new MyMethod3Delegate(instance.MyMethod3); myMethod3.BeginInvoke("parameterValue",new AsyncCallback(AfterMyMothod3),null); } public void AfterMyMothod3(IAsyncResult result){ AsyncResult async = (AsyncResult) result; MyMethod3Delegate DelegateInstance = (MyMethod3Delegate) async.AsyncDelegate; Console.WriteLine ("函数调用返回值:{0}/n", DelegateInstance.EndInvoke(result)); } |
首先为了使用委托我们声明了一个MyMethod3Delegate的委托,该委托说明一个参数和返回值为string的函数是符合条件的,所以我们在MyClass里面定义了一个MyMethod3的方法。该函数的型构符合上面的委托,所以我们可以在Button3点击的时候用这个方法实例化一个委托,然后我们使用异步的方式调用这个方法,为了得到返回结果我们写了AfterMyMothod3方法用来显示该函数的执行结果。运行程序点击Button3可以看到Output中输出的结果为MyMethod3带参数执行的结果。最后我给出如何传递多个参数的方法,我的例子是传递2个参数。代码如下:
// mutil-parameters passed delegate string MyMutilParamsDelegate(string parameter1,string parameter2); private void button4_Click(object sender, System.EventArgs e) { MyClass instance = new MyClass(); MyMutilParamsDelegate mutilParams = new MyMutilParamsDelegate(instance.MyMutilParameters); mutilParams.BeginInvoke("param1","params2",new AsyncCallback(AfterMutilParams),null); } public void AfterMutilParams(IAsyncResult result){ AsyncResult async = (AsyncResult) result; MyMutilParamsDelegate DelegateInstance = (MyMutilParamsDelegate) async.AsyncDelegate; Console.WriteLine ("多参数函数调用返回结果:{0}/n", DelegateInstance.EndInvoke(result)); } |