我们在写Remoting程序或者其他的一些应用程序的时候难免要和线程打交道使我们很容易就可以创建一个线程
但是它提供的创建线程和启动线程的方法没有明显的提供参数
假如我们要用线程来启动类里面一个带参数的方法该怎么办?下面就简单的介绍如何使用
NET提供的丰富的框架来实现这个功能
为了可以生动详细的介绍整个过程
我建立下面的一个
NET类
它也是要用线程启动的方法的载体
类如下所示
using System;
namespace WindowSAPplication
{
/// <summary>
/// Summary description for UrlFetcher
/// </summary>
public class MyClass{
// for method
private string _parameter;
public MyClass(string parameter){
this_parameter = parameter;
}
public void MyMethod(){
if(this_parameter!=null){
// do something
ConsoleWrite(this_parameter);
}
}
// for method
public MyClass(){}
// this method is privateBut it can be public or other
private void MyMethod(string parameter){
// do something
ConsoleWrite(parameter);
}
// Because delegate WaitCallbacks parameter Type is object
// I will convert it to string
public void MyMethod(object parameter){
thisMyMethod((string)parameter);
}
// for method
public string MyMethod(string parameter){
return 参数值为+parameter;
}
// for mutilparameters passed
public string MyMutilParameters(string paramstring param){
return 参数和参数连接结果为+param+param;
}
}
}
嘿嘿我的英语不行注释写的不好请见谅(因为使用的是英文的)希望没有影响您的阅读我想我有必要简单的说一下上面这个类里里面的所包含的内容首先包含两个构造函数一个带参数一个不带(这里可是有意安排的)通过类中其他方法的名字我想您一定猜出来我将介绍种方法来传递参数接下来我将逐一介绍首先我们看看如何启动一个线程首先我们可以用一个函数来实例化ThreadStart委托的一个实例然后在使用这个实例作为参数new线程(Thread)对象最后将这个线程Start就可以了想了解更多请参考MSDN文档的Thread部分
为了测试我们的结果我建立了一个WinForm的工程其中有一个Form和个按钮如果你需要所有的源码请发送邮件到wu如果我有时间我会给你发过去的接下来是每种方法的详细描述
使用构造函数来传递参数
众所周知我们可以使用一个带参数的构造函数来构造对象既然这样我们可以利用构造函数先将要使用的参数值传递到对象里面的内部变量上然后再使用一个无参数的方法来使用这个参数(假装参数)简单的说就是在类里面声明一个变量专门用来保存函数需要的参数函数变成无参的形式这种方法的最大问题就是破坏了封装性虽然我们不能直接方法这些变量但是隐患总是存在的(或者说看上去不爽都可以)下面代码片断给出了如何使用这个方法来传递参数的详细内容这也是上面提到的个按钮中的一个按钮(Button)的Click代码为了有参数可传我在WinForm全局定义了一个如下的变量
// This is parameters value
private string myParameter = ParameterValue\n;
按钮事件如下所示
// passed parameters to thread by construct
private void button_Click(object sender SystemEventArgs e) {
MyClass instance = new MyClass(myParameter);
new Thread (new ThreadStart(instanceMyMethod))Start();
}
正如上面所说的我们使用构造函数传递参数到类里面去然后在使用上面所说的方法启动了一个线程我们可以在运行该程序后的output窗口中看到MyMethod的执行结果是(你也可以用一个TextBox或者其他什么东西直接显示在WinForm上)ParameterValue 看看函数体就知道这个结果是正确的是不是很简单
使用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 button_Click(object sender SystemEventArgs e) {
MyClass instance = new MyClass();
ThreadPoolQueueUserWorkItem (new WaitCallback (instanceMyMethod)myParameter);
}
因为QueueUserWorkItem的二个参数是object类型的所以我们要在MyClass里面定义两个MyMethod的重裁版本目的就是为了满足该方法的参数同样我们将参数myParameter传递进去了运行程序当我们点击Button的时候在output窗口中将会出现MyMethod将myParameter作为参数执行的结果显示出来
接下来是最后一种方法使用异步委托来实现参数的传递
同样有关委托的详细信息可以参考MSDN上面说的非常详细我们这里要使用到BeginInvoke和EndInvoke方法首先我们给出传递一个参数的方法如下所示
// passed parameter by asynchronous delegate
delegate string MyMethodDelegate(string parameter);
private void button_Click(object sender SystemEventArgs e) {
MyClass instance = new MyClass();
MyMethodDelegate myMethod = new MyMethodDelegate(instanceMyMethod);
myMethodBeginInvoke(parameterValuenew AsyncCallback(AfterMyMothod)null);
}
public void AfterMyMothod(IAsyncResult result){
AsyncResult async = (AsyncResult) result;
MyMethodDelegate DelegateInstance = (MyMethodDelegate) asyncAsyncDelegate;
ConsoleWriteLine (函数调用返回值{}\n DelegateInstanceEndInvoke(result));
}
首先为了使用委托我们声明了一个MyMethodDelegate的委托该委托说明一个参数和返回值为string的函数是符合条件的所以我们在MyClass里面定义了一个MyMethod的方法该函数的型构符合上面的委托所以我们可以在Button点击的时候用这个方法实例化一个委托然后我们使用异步的方式调用这个方法为了得到返回结果我们写了AfterMyMothod方法用来显示该函数的执行结果运行程序点击Button可以看到Output中输出的结果为MyMethod带参数执行的结果最后我给出如何传递多个参数的方法我的例子是传递个参数代码如下
// mutil
parameters passed
delegate string MyMutilParamsDelegate(string parameterstring parameter);
private void button_Click(object sender SystemEventArgs e) {
MyClass instance = new MyClass();
MyMutilParamsDelegate mutilParams = new MyMutilParamsDelegate(instanceMyMutilParameters);
mutilParamsBeginInvoke(paramparamsnew AsyncCallback(AfterMutilParams)null);
}
public void AfterMutilParams(IAsyncResult result){
AsyncResult async = (AsyncResult) result;
MyMutilParamsDelegate DelegateInstance = (MyMutilParamsDelegate) asyncAsyncDelegate;
ConsoleWriteLine (多参数函数调用返回结果{}\n DelegateInstanceEndInvoke(result));
}
由于篇幅关系代码就不作详细说明了有不正确的地方请指正谢谢阅读!