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

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

namespace ThreadParameterDemo
{
public class FunctionClass
{
public static string TestFunction(string name, int age)
{
//内部处理省略
return name + " 的年龄是:" + age;
}
}
}

通过实体来来封装:

namespace ThreadParameterDemo
{
/// <summary>
/// 过渡类
/// </summary>
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程序在退出的时候,不会为你自己主动退出该线程。也就是实际上你的应用程序未结束。

MSDN推荐:多线程方法调用提供參数的最好办法是将目标方法包裹在类中,并为该类定义字段,这些字段将被用作新线程的參数。

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

BackgroundWorker 类

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

C# 多线程參数传递的更多相关文章

  1. java參数传递机制浅析

    欢迎转载,转载请声明出处! ----------------------------------------- 前言: java语言中,參数的传递仅仅有一种机制.那就是值传递. 举例: 以下将通过几个 ...

  2. c++參数传递

    定义: 形參:指出如今Sub 和Function过程形參表中的变量名.数组名,该过程在被调用前.没有为它们分配内存.其作用是说明自变量的类型和形态以及在过程中的作用.形參能够是除定长字符串变量之外的合 ...

  3. FPGA编程基础(一)--參数传递与寄存器使用

    一.參数映射 參数映射的功能就是实现參数化元件.所谓的"參数化元件"就是指元件的某些參数是可调的,通过调整这些參数从而可实现一类结构类似而功能不同的电路.在应用中.非常多电路都可採 ...

  4. activity之间參数传递&amp;&amp;获取activity返回值&amp;&amp;activity生命周期

    Activity之间參数传递 A activity想将參数传给B activity时能够利用Intent将消息带过去 Intent intent = new Intent(this,BActivity ...

  5. 再次学习javascript中的參数传递

     javascript中的全部函数的參数传递都是依照值传递的,做了以下測试:    function addTen(num){ num +=10; return num; } var count = ...

  6. ionic新手教程第七课-简要说明几种界面之间的參数传递及优缺点

    截至2016年4月13日19点32分,我公布的ionic新手教程,已经公布6课了, 总訪问量将近6000,平均每节课能有1000的訪问量.当中訪客最多的是第三课有2700的訪客. watermark/ ...

  7. Fragment进阶(四)-----&gt;參数传递3种写法

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  8. 关于mybatis中,批量增删改查以及參数传递的问题

    1.參数传递的问题 大多数情况下,我们都是利用map作为參数,而且大部分情况下都是仅仅有一个參数. 可是,我们也能够利用@param注解,来传入多个參数,此时,mybatis会自己主动将參数封装成ma ...

  9. int 0x13中断的參数传递

    int 0x13中断向量所指向的中断服务程序实质上就是磁盘服务程序. 用途:将指定扇区的代码载入到内存的指定位置. 因此,在使用int 0x13中断时要将參数传递给服务程序: 比如:将指定扇区和载入的 ...

随机推荐

  1. 004 Java的一次面试题,学长列举

    据说是Java的面试题,感觉有些汗颜,所以决定研究一下. 1.线程.进程.协程的区别,他们怎么进行线程的交互? 2.k8s内的scheduler怎么做的,流程?跟etcd怎么交互? 3.hashmap ...

  2. day30 网络编程 之进程,线程,协程

    进程点进去 线程点进去 协程点进去 什么是进程 进程(有时称为重量级进程)是一个执行中的程序.每个进程都拥有自己的地址空间.内存.数据栈以及其他用于跟踪执行的辅助数据.同一个程序执行两次,属于是两个不 ...

  3. 最长不下降子序列nlogn

    b[i]表示长度为i的最长不下降子序列的最小末尾元素的值显然它是单调递增的,满足二分性质,然后就可以愉快地二分啦. #include<iostream> #include<cstdi ...

  4. jenkins+springboot+svn linux 自动化部署

    需要下载 publish over ssh 插件(远程上传项目到服务器) Maven Integration plugin 插件(构建maven项目) 然后将各种配置配置好 最终项目在服务器上的路径是 ...

  5. lvs负载均衡概述

  6. angular笔记_6

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. sql的简单操作

    mysql 一.mysql简介和安装 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应 ...

  8. Centos6.5部署Rsyslog-日志的存储方式及监测服务状态

    1.以IP地址命名 在/etc/rsyslog.conf中加入如下配置,并做好备注.添加这三行配置之后,远程日志会被单独输出到一个以IP命名的日志文件中. #IP format by zhz at x ...

  9. LOJ.6073.[2017山东一轮集训Day5]距离(可持久化线段树 树链剖分)

    题目链接 就是恶心人的,简单写写了...(似乎就是[HNOI2015]开店?) 拆式子,记\(dis_i\)为\(i\)到根节点的路径权值和,\(Ans=\sum dis_{p_i}+\sum dis ...

  10. Scrapy基础(十)———同步机制将Item中的数据写在Mysql

      前面讲解到将Item中的所有字段都已经填写完成,那么接下来就是将他们存储到mysql数据库中,那就用到了pipeline项目管道了:  对项目管道的理解:做一个比喻,爬取好比是开采石油,Item装 ...