C#基础知识回顾--线程传参

  在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数,

也不能有返回值。如果希望传递参数给执行函数,则可以使用带参数的ParameterizedThreadStart委托,

          public delegate void ParameterizedThreadStart(Object obj)

可以将要传送给线程函数的信息封装为一个对象,然后调用Thread类的以下构造函数

          public Thread (ParameterizedThreadStartstart)

启动线程时,向其传送一个参数信息

          Thread t = new Thread(new ParameterizedThreadStart(线程函数));
           t.Start(object nParam);

其中object nParam就是要传递的参数,之所以使用object类型,那是因为nParam可以是任何class类型,这样你就

可传递任何类型给执行函数.

根据参数个数和返回值的不同又分为以下几种情形

一.单参数、无返回值

  这是最简单最直接的情形,无需做其他处理,直接传递

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;  

namespace ThreadAbort
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("主线程开始");
            //创建线程对象
            MyThread obj = new MyThread();
            Thread th = new Thread(new ParameterizedThreadStart(obj.SomeLongTask));
            th.IsBackground = true;
            th.Start(10);//启动线程,传递参数10
            th.Join();
            System.Console.WriteLine("主线程结束");
        }
    }  

    class MyThread
    {
        public void SomeLongTask(object obj)
        {
            int n = Convert.ToInt32(obj); //将接收的参数转换为需要的类型
            System.Console.WriteLine("辅助线程开始...");
            for (int i = 0; i <= n; i++)
            {
                System.Console.WriteLine(i);
                Thread.Sleep(100);
            }
        }
    }
}

 

二.多参数、有返回值

需要创建一个参数辅助类用于传递参数和返回值,例如:

 

    class ThreadMethodHelper
    {
          //线程输入参数
          public intx;
          public inty;
          //函数返回值
          public long returnVaule;
    }

然后改造线程函数为ParameterizedThreadStart委托支持的形式

   public void SomeFunc(object argu)
   {
          long ret = 0;
          intx = (arguas ThreadMethodHelper).x;
          inty = (arguas ThreadMethodHelper).y;
          //使用x和y完成一些工作,结果保存在ret中
          (arguas ThreadMethodHelper).returnVaule= ret;
    }

 

最后就可以使用辅助类进行线程操作了

 

MyThreadobj= new MyThread();
varargu= new ThreadMethodHelper();

//设定线程函数参数
argu.x= 100; argu.y= 200;

//创建线程对象
Thread t = new Thread(new ParameterizedThreadStart(obj.SomeFunc));

//启动线程,向线程传送线程参数
t.Start(argu);

//主线程干其他事……
t.Join();//等待辅助线程结束

Console.WriteLine(argu.returnVaule); //取回线程结果

例1:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;  

namespace ThreadTest
{
    class ThreadMethodHelper
    {
        //线程输入参数
        public int x;
        public int y;
        //函数返回值
        public long returnVaule;
    }
    class MultiParas
    {
        public static void SomeTask(object argu)
        {
            long ret = 0;
            int x = (argu as ThreadMethodHelper).x;
            int y = (argu as ThreadMethodHelper).y;
            //使用x和y完成一些工作,结果保存在ret中
            ret = x * y;
            (argu as ThreadMethodHelper).returnVaule= ret;
        }
        static void Main(string[] args)
        {
            System.Console.WriteLine("主线程开始");
            ThreadMethodHelper arg = new ThreadMethodHelper{x = 10, y = 100};
            //创建线程对象
            Thread th = new Thread(new ParameterizedThreadStart(SomeTask));
            //Thread th = new Thread(SomeTask);//这样写也可以
            th.IsBackground = true;
            th.Start(arg);//启动线程,传递参数10
            th.Join();
            Console.WriteLine("the result is :" + arg.returnVaule);
            System.Console.WriteLine("主线程结束");
        }
    }
}

例2:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;  

namespace UseArray
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread th = new Thread(DoWithArray);
            ThreadMethodHelper argu = new ThreadMethodHelper();
            argu.arr = new int[] { -1, 9, 100, 78, 23, 54, -90 };
            th.Start(argu);
            th.Join();
            Console.WriteLine("数组元素清单");
            foreach (int i in argu.arr)
            {
                Console.Write(i.ToString() + "  ");
            }
            Console.WriteLine();
            Console.WriteLine("最大值:{0}", argu.MaxValue);
            Console.WriteLine("最小值:{0}", argu.MinValue);
            Console.WriteLine("总和:{0}", argu.Sum );
            Console.WriteLine("平均值:{0}", argu.Average );  

            Console.ReadKey();
        }  

        static void DoWithArray(object  obj)
        {
            ThreadMethodHelper argu = obj as ThreadMethodHelper;
            for (int i = 0; i < argu.arr.Length; i++)
            {
                if (argu.arr[i] > argu.MaxValue)
                    argu.MaxValue = argu.arr[i];
                if (argu.arr[i] < argu.MinValue)
                    argu.MinValue = argu.arr[i];
                argu.Sum += argu.arr[i];
            }
            argu.Average = argu.Sum / argu.arr.Length;
        }
    }  

    //封装线程的输入和输出信息
    class ThreadMethodHelper
    {
        //线程输入参数
        public int[] arr;
        //函数返回值
        public int MaxValue=0;
        public int MinValue=0;
        public long Sum=0;
        public double Average=0;
    }
} 

 

时间: 2024-10-23 14:15:23

C#基础知识回顾--线程传参的相关文章

Java基础知识回顾--线程

基本概念 线程是一个程序内部的顺序控制流 Java的线程是通过java.lang.Thread类来实现的.main函数是一个主线程,用户可以通过创建Thread的实例来创建新的线程.每一个线程都必须实现run方法.通过Thread类的start方法来启动一个线程. 两种方式实现,一种是线程类实现Runnable接口:二种就是定义一个Thread的子类并重写其run方法. public class TestThread1 { public static void main(String args[

委托/事件/线程传参简单理解

写了很多代码,但几乎都没写过委托/事件/线程传参方面应用的代码 因此自己总很容易理解后又遗忘 今天又重温了一下 因此以最简单的方式的代码方式写下来帮助理解 1.线程传参[简单几行代码]    1 static void Main(string[] args) 2         { 3             if (ThreadPool.QueueUserWorkItem(new WaitCallback(Program.WritePara), "这是传进去的参数")) 4     

《非常网管:网络管理从入门到精通(修订版)》——第1章 网络基础知识回顾1.1 计算机网络基础

第1章 网络基础知识回顾 古语云:"练武不练功,到老一场空",学习网络的基础理论就像练功一样重要.本章主要介绍网络的基础.网络的体系结构.ISO/OSI(International Standard Organization/Open System Interconnection,国际标准化组织提出的开放系统互联)参考模型.TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议),其间穿插大量的实验和技巧,有

《CCNP SWITCH 300-115学习指南》——第1章 基础知识回顾

第1章 基础知识回顾CCNP SWITCH 300-115学习指南在正式进入CCNP SWITCH这门针对园区网交换技术的课程之前,我们首先快速地回顾一遍CCNA中的相关知识点并简要地介绍其中部分技术,以便于本书内容的理解.由于这里提到的所有技术都是独立存在的,如生成树或虚拟LAN(VLAN),因此本章将这些基础知识汇总到一起进行复习,并且在后续章节中将不再重复类似的基础讲解. 如果读者十分了解交换术语,并对交换技术有着基本的认识,建议跳过此章,直接从第2章开始阅读. 本章涵盖如下CCNA基础交

【JavaScript】javaScript基础知识回顾

我们首先对JavaScript的基础进行回顾. 1.浏览器的对象树 总浏大纲,还是要先看浏览器的对象树: 如1.1浏览器的对象树.png 2.window对象常用方法 alert('信息'):      消息框 prompt('提示信息',默认值): 标准输入框 confirm( ):      确认框 open( ):      打开一个新窗口 close( ):     关闭窗口 3.Form表单对象 访问表单的方式:     *  document.forms[n]     *  docu

java基础-关于Java的传参问题,javaee

问题描述 关于Java的传参问题,javaee public class TestCollection { public static void main(String[] args) { TestCollection t = new TestCollection(); char ch = 'y'; t.test(ch); } public void test(String str){ System.out.println("i am a string"); } public void

C#基础知识回顾---你不知道的Lazy&lt;T&gt;

    对象的创建方式,始终代表了软件工业的生产力方向,代表了先进软件技术发展的方向,也代表了广大程序开发者的集体智慧.以new的方式创建,通过工厂方法,利用IoC容器,都以不同的方式实现了活生生实例成员的创生.而本文所关注的Lazy<T>也是干这事儿的.不过,简单说来,Lazy<T>要实现的就是按"需"创建,而不是按时创建. 我们往往有这样的情景,一个关联对象的创建需要较大的开销,为了避免在每次运行时创建这种家伙,有一种聪明的办法叫做实现"懒对象&q

C#用线程传参下载文件的代码

下载 using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Net; using System.IO;using System.Text;using System.Threading; private void button6_Click(object sender, System.EventArg

关于C#基础知识回顾--反射

其实说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!反射的核心是System.Type.System.Type包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型信息   反射(reflection)是一种允许用户获得类型信息的C#特性.术语"反射"源自于它的工作方式: Type对象映射它所代表的底层对象.对Type对象进行查询可以获得(反射)与类型相关的信息.反射是一种 功能强大的机制,它允许学习和使用只在运行时才能知道的类型功能. 这些是官方定义,