如何在调用线程的时候传递参数
如何在调用线程的时候传递参数

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

复制C#代码保存代码
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全局定义了一个如下的变量:

复制C#代码保存代码
// This is parameter's value
private string myParameter = "ParameterValue\n";

按钮事件如下所示:

复制C#代码保存代码
// 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类型的。详细内容请看下面的代码。

复制C#代码保存代码
// 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方法。首先我们给出传递一个参数的方法如下所示:

复制C#代码保存代码
// 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个参数。代码如下:

复制C#代码保存代码
// 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));
}

posted on 2007-04-13 20:46 zwgood 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/zw0736/archive/2007/04/13/712541.html

如何在调用线程的时候传递参数相关推荐

  1. 《线程管理:传递参数、确定线程数量、线程标识》

    参考<c++ Concurrency In Action >第二章做的笔记 目录 传递参数 量产线程 线程标识 传递参数 thread构造函数的附加参数会拷贝至新线程的内存空间中,即使函数 ...

  2. jmeter解决不同线程组之间传递参数问题

    jmeter解决不同线程组之间传递参数问题 参考文章: (1)jmeter解决不同线程组之间传递参数问题 (2)https://www.cnblogs.com/yingchen/p/5110335.h ...

  3. jmeter debug sample不在查看结果树中显示_Jmeter线程组间传递参数

    现在做测试和以前不太一样了,以前只要站在一个用户的角度做端到端的UI测试就可以了,现在不会做接口测试,出去都不好意思和别人打招呼.那提到接口测试,就不得不提一下接口测试利器Jmeter,大家也都知道, ...

  4. Jmeter线程组间传递参数

    现在做测试和以前不太一样了,以前只要站在一个用户的角度做端到端的UI测试就可以了,现在不会做接口测试,出去都不好意思和别人打招呼.那提到接口测试,就不得不提一下接口测试利器Jmeter,大家也都知道, ...

  5. Groovy小结:java调用Groovy方法并传递参数

    @(JAVA总结) 1. 场景描述 在网上查了资料发现,java有三种方式调用groovy脚本.但是真正在实际的服务器环境中,嵌入groovy脚本往往需要满足下面的条件: 可以直接调用groovy脚本 ...

  6. java调接口传值_关于调用第三方接口时传递参数是File类型的解决方式

    正版编程与类型系统讲解基于的应用 77.35元 (需用券) 去购买 > 最近项目,需要我调用另一个项目中的某个接口,接口的入参为File类型,要拿到此接口返回的数据@ApiOperation(& ...

  7. java调用shell脚本并传递参数

    最近业务上需要java调用执行shell脚本进行一些业务处理,写了个demo,记录下. 主要代码 @RequestMapping("/copy/database")@Respons ...

  8. js向jsf调用后台方法并传递参数

    使用p:remoteCommand来达到复杂的异步刷新取值 大家请注意,这个方法可以真正的解决在jsf中通过js调用后台bean方法并获取bean方法返回值的问题. 同样,首先我们要写两个jsf组件, ...

  9. 调用python脚本并传递参数json格式_使用 Python 处理 JSON 格式的数据

    如果你不希望从头开始创造一种数据格式来存放数据,JSON 是一个很好的选择.如果你对 Python 有所了解,就更加事半功倍了.下面就来介绍一下如何使用 Python 处理 JSON 数据. JSON ...

最新文章

  1. Vagrant的用法
  2. 读取文档时出现问题129_springboot读取配置文件的自定义内容时出现中文乱码
  3. 关于Java抽象类,接口与实现接口及派生类继承基类
  4. 【转载】编程生涯 21 载,那些我踩过的坑
  5. 阿里:千亿交易背后的0故障发布
  6. 一起玩Docker之1——Ubuntu配置安装Docker运行环境并安装(Ubuntu、Centos)镜像
  7. 【高斯和拉普拉斯为什么分别对应L2和L1?】差分隐私系统学习记录(五)
  8. 华为今日正式发布鸿蒙!中国人终于有了自己的手机操作系统
  9. oracle有没有mysql if_Oracle中没有 if exists(...)
  10. php 清除指定session,PHP如何操作指定的session?
  11. Markdown的下载和操作介绍
  12. linux pbs 安装包,【Linux】单计算机安装PBS系统(Torque)与运维
  13. 彩虹也能“生”出小彩虹
  14. 从函数型数据到光滑函数
  15. 设计模式---004策略模式(转载自我的老师 Alley-巷子)
  16. 克里斯蒂安贝尔_克里斯蒂安贝尔现身机场,身材瘦到认不出来,蝙蝠侠又开始减重了...
  17. NestedScrollView 滚动到顶部
  18. 如何使用计算机查询本机网卡信息,本机mac地址查询的三种方法
  19. 如何把图片分辨率调低?如何调整照片的分辨率?
  20. 超好看的导航页面(静态页面)

热门文章

  1. easyui的tree获取父节点_力扣 1519——子数中标签相同的节点数
  2. 计算机启动进入不了桌面图标,电脑开机只显示桌面背景而无桌面图标怎么办
  3. jmeter达梦数据库
  4. Spark(2)——小用RDD
  5. 用python实现TCP协议传输功能(客户端代码)
  6. |(与或移位等)的工程运用
  7. CentOS生成自签名证书配置Apache https
  8. UBoot讲解和实践-----------讲解(一)
  9. 分数化成有限小数的方法_[153]各种循环小数化成分数的方法归纳
  10. C++ 程序内存泄漏检测方法