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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

C# 泛型的简单理解(安全、集合、方法、约束、继承)

泛型允许你在编译时实现类型安全。它们允许你创建一个数据结构而不限于一特定的数据类型。然而,当使用该数据结构时,编译器保证它使用的类型与类型安全是相一致的。泛型提...

10210
来自专栏恰童鞋骚年

.NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

开篇:在上一篇中,我们了解了自动属性、隐式类型、自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类、匿名方法以及常用的扩展方法。虽然,都是很常见的东西,...

12630
来自专栏博客园

.NET Core中延迟单例另一种写法【.NET Core和.NET Framework的beforefieldinit差异】

   前段时间在反编译代码时无意间看到在类中有一个BeforeFieldInit特性,处于好奇的心态查了查这个特性,发现这是一个关于字段初始化时间的特性【提前初...

19240
来自专栏Create Sun

基础拾遗------反射详解

前言 MSDN定义:通过 System.Reflection 命名空间中的类以及 System.Type,您可以获取有关已加载的程序集和在其中定义的类型(如类、...

32660
来自专栏蘑菇先生的技术笔记

探索c#之递归APS和CPS

30870
来自专栏大内老A

通过实例模拟ASP.NET MVC的Model绑定机制:数组

[续《通过实例模拟ASP.NET MVC的Model绑定机制:简单类型+复杂类型]》]基于数组和集合类型的Model绑定机制比较类似,对于绑定参数类型或者参数类...

30890
来自专栏技术博客

C#泛型委托Predicate、Action、Func

Predicate泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。 ...

16120
来自专栏菩提树下的杨过

再谈Silverlight中的对象序列化/反序列化

曾经发过一篇如何在Silveright中利用XmlSerializer序列化对象的文章“Silverlight中的序列化”,限于当时的认识有限,一度以为silv...

22480
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第4章 Query查询之基础

Query查询 首先,我们先来看一下query的语法结构图: ? Query语法提供了一种查询working memory中符合约束条件的FACT对...

27490
来自专栏Golang语言社区

厚土Go学习笔记 | 28. go语言没有类 却可以在结构体或任意类型定义方法

在go语言中没有类。可是,是有方法的。 给结构体定义方法,在对应的 func 和方法名之间,加上方法的接收者就可以了。 比如,我们定义了一个结构体 type V...

38480

扫码关注云+社区

领取腾讯云代金券