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. BeanFactory和FactoryBean的区别

    转自:http://blog.csdn.net/wangbiao007/article/details/53183764 1.BeanFactory BeanFactory是IOC最基本的容器,负责生 ...

  2. Philosopher’s Walk(递归)

    In Programming Land, there are several pathways called Philosopher’s Walks for philosophers to have ...

  3. Stm32基础

    Stm32基础 目录 常用功能函数 跑马灯实验 蜂鸣器实验 按键实验 端口复用与重映射 常用功能函数 初始化gpio函数 作用:初始化一个或者多个io口(同一组)的工作方式和速度该函数主要是操作GPI ...

  4. 分布式事务?咱先弄明白本地事务再说 - ACID

      过去一段时间面试的同学,对于数据库事务,可以按照配置正常使用,但很多都无法讲清楚和理解数据库事务这个东西真正的意义,以及互联网兴起以后,当今数据库在ACID面前面临怎样的问题和抉择. 事务,是各大 ...

  5. C++雾中风景13:volatile解惑

    笔者入职百度时,二面面试官的让我聊聊C++之中的volatile关键词.volatile在Java和C++之中的差别可谓是天差地别,我只是简单聊了聊Java之中的volatile,面试官对我的回答并不 ...

  6. IconFont 图标制作和使用

    一.制作:IcoMoon 这个教程一搜一大把,是很方便快捷的一种方式,提供上传.编辑或者选择IcoMoon-Free下载可以直接拿来用了. 网址:https://icomoon.io/app/ 上传需 ...

  7. IDEA 配置datasource,提升编码效率,让你在 Mapper.xml 中编写sql可以飞起来~

    IDEA 2018 创建springboot工程后,如果你打开一个.sql文件,或者一个mybatis的mapper.xml文件,会提示: No data source are configured ...

  8. 部署前准备--使用Mysql之Django Debug Toolbar安装以及配置

    python -c "import django ;print(django.__path__);" 查看python的全局配置 vi /usr/local/lib/python3 ...

  9. Docker命令使用详解(转)

    如果各位看官熟悉 Git 和 GitHub ,可与 Docker 做个类比,可更加容易理解 Docker 和 Docker Hub 及两者关系. 1. docker version 显示 Docker ...

  10. GMA Round 1 逃亡

    传送门 逃亡 你在森林中,遇到了一只老虎.此时此刻,老虎在(0,0)的位置,你在(2,1)的位置. 你开始沿着一条林间小路逃亡,移动向量是$(\frac{\sqrt{6}}{2},\frac{\sqr ...