C# 多线程參数传递

1、通过实体类来传递(能够传递多个參数与获取返回值),demo例如以下:

须要在线程中调用的函数:

namespace ThreadParameterDemo
{
    public class FunctionClass
    {
        public static string TestFunction(string name, int age)
        {
            //内部处理省略
            return name + " 的年龄是:" + age;
        }
    }
}
namespace ThreadParameterDemo
{
    ///
    /// 过渡类
    ///
    public class TransitionalClass
    {
        private string name = string.Empty;
        private int age;
        public string acceptResults = string.Empty;
        public TransitionalClass(string name, int age)
        {
            this.name = name;
            this.age = age;
        }

        public void TestFunction()
        {
            acceptResults = FunctionClass.TestFunction(this.name, this.age);
        }
    }
}
private void Form1_Load(object sender, EventArgs e)
        {
            //实例化ThreadWithState类。为线程提供參数
            TransitionalClass tc = new TransitionalClass(" Jack", 42);
            // 创建运行任务的线程,并运行
            Thread t = new Thread(new ThreadStart(tc.TestFunction));
            t.Start();
            //获取返回值。通过 tc.acceptResults;
        }

小注:

必须注意IsBackground的问题。假设IsBackground为false的,则Windows程序在退出的时候,不会为你自己主动退出该线程。也就是实际上你的应用程序未结束。

这样的方法的长处是,不论什么时候想要启动新线程。都能够创建类的新实例,该实例带有自身的參数。

ThreadStart中的函数是没有返回值和參数的
2、异步调用中的參数和返回值
能完美解决參数和返回值的是使用异步调用的方式。异步调用和Thread相比,一个最大的劣势是不能控制其优先级。

详细代码例如以下:

public delegate string delegateFunction(string name,int age);//托付
        delegateFunction df;
        private void Form1_Load(object sender, EventArgs e)
        {
            //指向须要调用的方法
            df = new delegateFunction(FunctionClass.TestFunction);
            string name = "my name";//输入參数
            int age = 19;
            IAsyncResult result = df.BeginInvoke(name,age, null, null);
            string myResult = df.EndInvoke(result);//用于接收返回值
            MessageBox.Show(myResult);
        }

简化:

public Func  df;//托付
        private void Form1_Load(object sender, EventArgs e)
        {
            //指向须要调用的方法
            df += FunctionClass.TestFunction;
            string name = "my name";//输入參数
            int age = 19;
            IAsyncResult result = df.BeginInvoke(name, age, null, null);
            string myResult = df.EndInvoke(result);//用于接收返回值
            MessageBox.Show(myResult);
        }

小注:

通过这样的方式生成新线程是运行在后台的(background),优先级为normal

3、使用 BackgroundWorker

多线程返回值最简单方法是:使用 BackgroundWorker 组件来管理线程,在任务完毕时引发事件,然后用事件处理程序处理结果。

小注:
BackgroundWorker 组件用来运行诸如数据库事务、文件下载等耗时的异步操作。
在应用程序中加入一个BackgroundWorker实例,假设用的是VS,能够从工具上直接拖到应用程序:

BackgroundWorker backgroundWorker1 = new BackgroundWorker();

为了開始在后台操作,必须调用BackgroundWorker的RunWorkerAsync()方法。当调用此方时,BackgroundWorker 通过触发DoWork 事件,開始运行后台操作。DoWork 事件的代码是在还有一个线程里运行的。
当后台操作完毕以后,不管是completed 还是cancelled,则RunWorkerCompleted 事件被触发。通过此方法能够将后台操作的完毕结果反馈给用户。
另外,通过RunWorkerCompletedEventArgs实例的Cancelled 属性,以推断是否是Cancel操作使得后台操作终止。

详细demo例如以下:

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            //TransitionalClass tc = new TransitionalClass("xiaoming", 10);
            //ThreadPool.QueueUserWorkItem(new WaitCallback(TransitionalClass.TestFunction), tc);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.TestArea2();
        }

        private System.ComponentModel.BackgroundWorker BackgroundWorker1
    = new System.ComponentModel.BackgroundWorker();

        private void TestArea2()
        {
            InitializeBackgroundWorker();

            AreaClass2 AreaObject2 = new AreaClass2();
            AreaObject2.Base = 30;
            AreaObject2.Height = 40;

            // Start the asynchronous operation.

            BackgroundWorker1.RunWorkerAsync(AreaObject2);
        }

        private void InitializeBackgroundWorker()
        {
            // Attach event handlers to the BackgroundWorker object.

            BackgroundWorker1.DoWork +=
                new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork);
            BackgroundWorker1.RunWorkerCompleted +=
                new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted);
        }

        private void BackgroundWorker1_DoWork(
            object sender,
            System.ComponentModel.DoWorkEventArgs e)
        {
            //在运行DoWork 事件时,DoWorkEventArgs 实例的Result 属性,返回值到用户;在RunWorkerCompleted 事件里,RunWorkerCompletedEventArgs 实例的Result 属性接收值;
            AreaClass2 AreaObject2 = (AreaClass2)e.Argument;
            // Return the value through the Result property.

            e.Result = AreaObject2.CalcArea();
        }

        private void BackgroundWorker1_RunWorkerCompleted(
            object sender,
            System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            // Access the result through the Result property.

            double Area = (double)e.Result;
            MessageBox.Show("The area is: " + Area.ToString());
        }
    }
}

demo代码来自MSDN:点击打开链接

參考文章:点击打开链接

C# 多线程參数传递
FunctionClass类新增,測试函数例如以下:
public static void TestFunction2(string name, int age)
        {
            //内部处理省略
        }

调用例如以下:

private void Form1_Load(object sender, EventArgs e)
        {
            Thread t1 = new Thread(new ThreadStart(delegate
            {
                FunctionClass.TestFunction2("eee", 5);
            }));
            t1.Start();
        }

小注:

假设通过WCF来调用的话,应该把起线程的函数放到服务端,假设放到client。非常easy由于WCFclient的时间限制,造成造成主程序的莫名崩溃。

崩溃的原因主要是clientwcf响应时间是有限制。

Original: https://www.cnblogs.com/brucemengbm/p/7402456.html
Author: brucemengbm
Title: C# 多线程參数传递

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/539880/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 交换两个变量的值

    异或运算的巧用 → 不用额外的变量,如何交换两个变量的值? public class xorExchange { public static void main(String[] …

    Java 2023年6月6日
    0100
  • 美团动态线程池实践思路,开源了

    大家好,今天我们来聊一个比较实用的话题,动态可监控的线程池实践,全新开源项目(DynamicTp)地址在文章末尾,欢迎交流学习。 写在前面 稍微有些Java编程经验的小伙伴都知道,…

    Java 2023年6月14日
    071
  • 22部漫威电影大合集和观影顺序

    【原文链接】:https://blog.tecchen.tech ,博文同步发布到博客园。由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容。欢迎访问我的…

    Java 2023年6月6日
    094
  • springboot读取resources下文件方式

    之前使用读取resources下的json文件,后来发现不通用,在这里做一些记录。 打成jar包之后,没有办法读取里面的路径。使用流的方式进行 一:实践 1.说明 使用了org.s…

    Java 2023年5月30日
    057
  • nginx+tomcat 架构 HttpServletRequest.getScheme()获取正确的协议

    问题:通过浏览器输入https://www.mysite.com,后台通过request.getScheme()获取到的确实http而不是https 通过request.getRe…

    Java 2023年5月30日
    068
  • Spring使用外部属性文件

    一、在 Spring Config 文件中配置 Bean 时,有时候需要在 Bean 的配置里添加系统部署的细节信息, 如文件路径,数据源配置信息。而这些部署细节实际上需要在配置文…

    Java 2023年5月30日
    052
  • uni模板

    html;gutter:true; export default { components:{ }, data () { return {} }, onLoad () {}, on…

    Java 2023年5月29日
    074
  • 部署-jenkins发布项目到windows环境

    使用openSSH的方式 如果我们项目的部署环境在windows环境上,我们可以选择给服务器安装openSSH的方式,然后以脚本的方式进行部署。也可以通过web容器的对外访问地址,…

    Java 2023年6月7日
    070
  • Python 的线程与进程

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月8日
    079
  • 多线程与高并发(四)—— 根据 HotSpot 源码讲透 Java 中断机制

    前言 我们首先介绍中断的三个 APPI 及其底层代码,在对方法的实现有了清晰的认知后,再结合场景谈谈什么是中断,以及中断该如何正确使用? 一、中断方法 1. isInterrupt…

    Java 2023年6月9日
    045
  • JAVA PDF 截取N页,生成新文件,转图片

    JAVA PDF 截取N页,生成新文件,转图片 import com.itextpdf.text.Document; import com.itextpdf.text.pdf.Pd…

    Java 2023年6月13日
    072
  • 力扣刷题之路——数组的旋转、遍历

    参考刷题顺序:力扣刷题顺序 涉及题目 189 轮转数组 396 旋转函数 54. 螺旋矩阵 59. 螺旋矩阵 II 498. 对角线遍历 189 轮转数组 自己的想法: 类似于题目…

    Java 2023年6月5日
    077
  • 6000字|22张图 带你彻底弄懂Zookeeper分布式锁

    前面我们剖析了Redisson的源码,主要分析了Redisson实现Redis分布式锁的15问,理清了Redisson是如何实现的分布式锁和一些其它的特性。这篇文章就来接着剖析Zo…

    Java 2023年6月16日
    072
  • 内存分析

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月7日
    074
  • Git与Gitee

    1.1Git 的优势 分支操作 大部分操作在本地完成,不需要联网 完整性保证 尽可能添加数据而不是删除或修改数据 分支操作非常快捷流畅 与 Linux 命令全面兼容 1.2Git流…

    Java 2023年6月13日
    090
  • java基本数据类型之间的转换

    基本数据类型之间的相互转换分为两种,分别是自动类型转换和强制类型转换。 自动类型转换 当需要从低级类型向高级类型转换时,java会自动完成从低级类型向高级类型转换。低级类型是指取值…

    Java 2023年6月7日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球