zoukankan      html  css  js  c++  java
  • .NET异步程序设计——给线程传递数据

    shanzm-2021年8月24日 19:51:26

    0. 前情说明:

    首先我们都知道,创建一个线程执行一个无参函数,则方式如下:

    //期望在线程中执行的函数
    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委托类型



    1. ParameterizedThreadStart类型的委托

    1.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函数中传递参数
    }
    
    

    1.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}");
    }
    


    2. 使用自定义类

    2.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);
    }
    

    2.2 获取返回值

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

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


    3. 使用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();
    }
    


    4. 参考以及文中源代码下载

    作者:shanzm
    欢迎交流,欢迎指教!
  • 相关阅读:
    xcode 快捷键大全、XCode常用快捷键图文介绍
    在ASP.NET Core 2.0 web项目中使用EntityFrameworkCore
    AspNetCore2身份验证
    @addTagHelper的使用
    Asp.net Mvc身份验证
    webAPi OData的使用
    Chrome及Chrome内核浏览器改变开发者工具字体大小
    银行卡号校验
    django静态文件
    django 简单路由配置
  • 原文地址:https://www.cnblogs.com/shanzhiming/p/15181943.html
Copyright © 2011-2022 走看看