北大青鸟中博
在线报名 | 成绩查询 | 中博南京校区 | 中博技术论坛 |
高中生就业方案 大学生就业方案 在职、转行、待业人员就业方案 中博校区环境 2008高考特招 北大青鸟招生公告 校庆6周年活动
您的位置:新闻动态 - 行业新闻

C#多线程参数传递
作者:教员 出处:中博 时间:2007-08-19

我们在写Remoting程序或者其他的一些应用程序的时候难免要和线程打交道,.Net使我们很容易就可以创建一个线程,但是它提供的创建线程和启动线程的方法没有明显的提供参数,假如我们要用线程来启动类里面一个带参数的方法该怎么办?下面就简单的介绍如何使用.NET提供的丰富的框架来实现这个功能。为了可以生动详细的介绍整个过程,我建立下面的一个.NET类,它也是要用线程启动的方法的载体。类如下所示:

using System;



namespace WindowsApplication1

{

/// <summary>

/// Summary description for UrlFetcher.

/// </summary>

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;

}



}

}



  嘿嘿,我的英语不行,注释写的不好请见谅(因为使用的是英文的),希望没有影响您的阅读。我想我有必要简单的说一下上面这个类里里面的所包含的内容。首先包含两个构造函数,一个带参数一个不带(这里可是有意安排的)。通过类中其他方法的名字我想您一定猜出来我将介绍3种方法来传递参数,接下来我将逐一介绍。首先我们看看如何启动一个线程,首先我们可以用一个函数来实例化ThreadStart委托的一个实例,然后在使用这个实例作为参数new线程(Thread)对象,最后将这个线程Start就可以了,想了解更多请参考MSDN文档的Thread部分。

  为了测试我们的结果我建立了一个WinForm的工程,其中有一个Form和4个按钮,如果你需要所有的源码请发送邮件到wu_jian830@hotmail.com,如果我有时间我会给你发过去的。接下来是每种方法的详细描述。

  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));

}


>>更多新闻

前一篇:迷你书:Visual Studio .NET使用技巧手册
后一篇:Java有能力抵挡LAMP的进攻吗?

 
在线咨询  
黄老师 陆老师
韩老师 值班老师
中心简介
校区简介
校区环境
关于北大青鸟
特色优势
常见问题解答
 
 
ACCP软件工程师课程
什么是ACCP
ACCP5.0课程介绍
各课程定位与特色
各阶段课程
教学模式
ACCP5.0课程体系
ACCP认证证书
 
关于中博   联系我们   校区招聘   友情链接
深圳北大青鸟 北京北大青鸟 北大青鸟杭州 北大青鸟 北大青鸟深圳 北大青鸟深圳罗湖 杭州北大青鸟 郑州北大青鸟 海淀北大青鸟
 
全国免费服务电话:800-828-5191(电信用户使用)
  报名咨询电话:0516 - 85628888 85629999 黄老师 陆老师
地址:徐州市解放南路181科技培训中心(六中对面)
乘车路线:11、19、20、65、39、60、51、64、609、游1、游2至和平路六中站下 苏ICP备08102142号