博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 多线程參数传递
阅读量:5332 次
发布时间:2019-06-15

本文共 5708 字,大约阅读时间需要 19 分钟。

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:

參考文章:

4、假设不如返回值的时候。应该怎么优雅的写呢?匿名函数啊偷笑

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响应时间是有限制。

转载于:https://www.cnblogs.com/brucemengbm/p/7402456.html

你可能感兴趣的文章
Git使用摘要
查看>>
基础总结篇之中的一个:Activity生命周期
查看>>
“cvSnakeImage”: 找不到标识符
查看>>
分布式文件系统HDFS 练习
查看>>
ORACLE 自治事物
查看>>
Spring --- java定时器,Spring定时器和Quartz定时器
查看>>
appium----【已解决】【Mac】环境配置提示“Xcode Command Line Tools are NOT installed!"
查看>>
没有没用的东西
查看>>
单据数据修改历史记录!
查看>>
React-使用装饰器
查看>>
python异常处理、断言
查看>>
Tomcat有很多方面,我从内存、并发、缓存四个方面介绍优化方法
查看>>
Hdu 1175 连连看(DFS)
查看>>
linux后台运行jar程序
查看>>
如何去掉idea里mybatis的.xml文件 sql 语句背景色
查看>>
关于Unity中NGUI的Checkbox复选框、Slider滑动条和Button的6种触发回调事件的方式
查看>>
linux文件种类及其扩展名
查看>>
【转载】Visual Studio + VA 常用快捷键
查看>>
Android SDK Manager国内无法更新的解决方案
查看>>
20145303刘俊谦 Exp8 Web基础
查看>>