多线程传参及返回值方式


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:多线程传参问题:

首先我们知道多线程接收参数这块比较严谨,不像我们日常调用函数一样ActionName(parameter p1) 这样简单明了。 接下来我们介绍下三种多线程传参方式


一、前情说明

该实例介绍多线程无参调用方式

/期望在线程中执行的函数
static void Do()
{
    Console.WriteLine("Create Thread");
}

//创建线程执行函数
static void Main(string[] ars)
{
    Thread thread=new Thread(Do);
    thread.Start();
    Console.ReadKey();
}

若是我们希望开新线程执行一个带有参数的方法,则上面的语句就无法执行了。

上面的Thread类构造函数Thread()在.NET中是有四重重载的。

上面使用的Thread对象的构造函数的参数类型是ThreadStart委托类型

二、ParameterizedThreadStart类型的委托

1.简单示例及说明

使用以ParameterizedThreadStart类型的委托为参数的Thread对象构造函数,并使用Thread.Start()来传递参数

Thread()方法在.net中有四个重载,我们可以使用其参数类型为ParameterizedThreadStart委托的构造函数,实现线程中执行带参数的函数,即往线程中传递数据。
结构:

  • 是使用Thread.Start(object param)传递参数的

  • ParameterizedThreadStart委托是:

    • 参数只能是一个
    • 参数类型是object类型
    • 无返回值的
  • 因为ParameterizedThreadStart委托的参数类型是object类型,所以我们需要修改期望在新线程中行的方法,将其参数改为object类型,在方法中使用时在进行拆箱

static void Do(object obj)
{
    int n = (int)obj;
    Console.WriteLine($"方法1:新开线程执行方法,其参数是{n}");
}
static void Main(string[] args)
{
    Thread thread = new Thread(Do);//这里的Do函数就是ParameterizedThreadStart类型的委托
    int n = 999;
    thread.Start(n);//在Start函数中传递参数
}


2.多参并获取返回值

程序自然是面向对象的,我们可以定义一个辅助类(注意不能使用结构体,结构体为值类型)

//临时辅助类
class TempClass
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Ret { get; set; }
}
//期望在新线程中执行的函数,并期望获取对参数操作的结果
static void DoWithParam(object obj)
{
    TempClass tempClass = obj as TempClass;
    tempClass.Ret = tempClass.X + tempClass.Y;
}
//创建线程并执行
static void Main(string[] args)
{
    Thread thread = new Thread(DoWithParam);
    TempClass tempClass = new TempClass() { X = 1, Y = 2 };
    thread.Start(tempClass);
    thread.Join();//注意这里等待thread线程执行完成
    Console.WriteLine($"实现获取到返回值:{tempClass.Ret}");
}

三 使用自定义类方式

1 . 简单示例及说明

将方法封装在类中,则在自定义类实例化的时候,实现传递参数

这里我们依旧是使用Thread对象的参数类型为ThreadStart类型的构造函数,但是我们需要在新线程中执行的有参函数封装在一个类中
在类的实例化时,实现传递参数
示例:
有一个需要在新线程中执行的有参函数如下

pubic void Do(string param)
{
    Console.WriteLine($"新开线程执行方法,其参数是{param}");
}

我们可以这样封装该方法,并在创建线程并执行该方法

//自定义类
public class MyClass
{
    public int param { get; set; }
    public void Do()
    {
        Console.WriteLine($"方法2:新开线程执行方法,其参数是{param}");
    }
}
//创建线程并执行
static void Main(string[] args)
{
    MyClass myClass=new MyClass(999);
    Thread thread =new Thread(myClass.Do);
}

获取返回值

思路一样,在自定义类中添加一个属性,作为返回值

class TempClass2
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Ret { get; set; }
    public void DoWithParam()
    {
        Ret = X + Y;
    }
}
static void Main(string[] args)
{
    TempClass2 tempClass2 = new TempClass2() { X = 1, Y = 2 };
    Thread thread = new Thread(tempClass2.DoWithParam);
    thread.Start();
    thread.Join();//注意这里表示tempClass线程执行完成
    Console.WriteLine($"实现获取到返回值:{tempClass2.Ret}");
}


四 使用Lambda表达式

Lambda 也是委托的一种, 在此我们可以直接以Lambda作为任务载体去传递参数 注意: 但返回值也是需要以上方式来获取的哦!!

这是目前最方便的往线程中传递数据的方案

//期望在新线程中执行的方法
static void Do(int n, int m)
{
    Console.WriteLine(n * m);
}

static void Main(string[] args)
{
    Thread thread1 = new Thread(() => Do(2, 3));//定义一个Lambda表达式,调用Do()函数
    thread1.Start();

    //其实这里我们就是可以将所有的函数逻辑直接写在Lambda表达式中,从而更加方便
    Thread thread2 = new Thread(() => { Console.WriteLine(2 * 3); });
    thread2.Start();
}


总结

提示:这里对文章进行总结:

大家使用多线程的时候,操作共享资源时需注意线程安全的问题哦!!
也可以了解下 同步、异步的概念 概念内容跟字面意思可不一样哦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值