[C#参考]主线程和子线程之间的参数传递
几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢?
主线程向子线程传递参数的方法
第一种方法:Thraed类有一个带参数的委托类型的重载形式,这个委托的定义如下:
public delegate void ParameterizedThreadStart(Object obj)
这个Thread类的构造方法的定义如下:
public Thread(ParameterizedThreadStart start);
下面的代码使用了这个带参数的委托向线程传递一个字符串参数:
public static void myStaticParamThreadMethod(Object obj)
{
Console.WriteLine(obj);
}
static void Main(string[] args)
{
Thread thread = new Thread(myStaticParamThreadMethod);
thread.Start("通过委托的参数传值");
}
注意这种形式,委托就是Thread要执行的方法,这个委托有一个类的实例对象作为参数。然后在Thread的Start()方法中把这个对象传进去。
如果使用了不带参数的委托,当然也能很正常的启动线程,别学傻了。
第二种方法:定义一个类来传递参数
class Program
{
static void Main(string[] args)
{
MyData myData = new MyData("abcd", );
Thread thread = new Thread(myData.ThreadMethod);
thread.Start(); Console.ReadKey();
}
}//class //定义一个类传递参数
public class MyData
{
private string d1;
private int d2; public MyData(string d1, int d2)
{
this.d1 = d1;
this.d2 = d2;
} public void ThreadMethod()
{
Console.WriteLine(d1);
Console.WriteLine(d2);
}
}//class
这种方法的特点是:子线程的执行入口是在另一个类中,这样正好可以借助这个类的成员函数,给子线程传参。
第三种方法:定义一个新的线程类,让所有的子线程类都继承自这个类
abstract class MyThread
{
Thread thread = null;
abstract public void run();
public void Start()
{
if (thread == null)
{
thread = new Thread(run);
thread.Start();
}
}
}
class Utility : MyThread
{
private string d1;
private int d2;
public override void run()
{
Console.WriteLine(d1);
Console.WriteLine(d2);
}
}//class
其实上面的两种方法的原理是一样的,这是一个面向数据,一个面向线程。
子线程向主线程传递参数
这里看到是传递参数,也就是说子线程要调用主线程的一个方法,然后把参数传递给主线程的那个方法。说一下方法是前面已经讲过的Invoke和BeginInvoke,但是那时调用主线程的方法并没有传递参数,今天看一下带参数的调用主线程的指定方法。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading; namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private int count = ; private delegate void DoWorkUIThreadDelegate();
public Form1()
{
InitializeComponent();
} private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(ThreadMethod);
thread.IsBackground = true;
thread.Start();
} private void ThreadMethod()
{
while (true)
{
//lblResult.Text = DateTime.Now.ToString();
//这句话不能直接调用,因为子线程不能直接调用UI线程中的控件
if (this.InvokeRequired)
{
this.BeginInvoke(new DoWorkUIThreadDelegate(DoWorkUIThread), null);
}
else
{
DoWorkUIThread();
} //子线程还是可以访问UI线程的普通变量的,只是不能访问控件
//因为普通变量是属于整个类的,属于整个进程的,各个线程时共享的
//对访问共享的数据,加一个lock的锁更加的好
count++;
Thread.Sleep();
} } private void DoWorkUIThread()
{
txtTime.Text = DateTime.Now.ToString() + " " + count;
}
}
}
上面的这种情况似乎用不着子线程给UI线程返回数据,反正子线程可以访问主线程的成员变量。但是另一种情况来了,当子线程不再UI线程所在的类的时候,也就是说子线程在一个工具类中,UI类new出来一个工具类完成一定的工作,UI类可以初始化工具类,但是工具类完成了一定任务后怎么通知UI类呢?现在有这种假设:
UI类要Socket连接网络,现在有一个SocketUtil工具可以完成这项任务,所以UI类就New出来一个SocketUtil,然后调用指定的函数,把IP和Port传递进去。在完成了一些任务以后,SocketUtil要反馈一些信息给UI类。让UI类显示反馈的信息。现在面临两个问题:
1. UI类怎么知道SocketUtil完成了这项任务,然后取显示数据呢?
2. UI类即使知道了什么时候显示信息,那么要显示的内容,UI类怎么知道是什么呢?
第一个问题的解决方法就是事件,利用事件就能在SocketUtil完成一些任务之后,通知UI类接下来怎么做。
第二个问题就是利用Invoke让子线程给主线程调用主线程的函数完成任务的时候,给一些参数。
这里就直接在同一个类中展示一下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading; namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private int count = ; private delegate void DoWorkUIThreadDelegate(string name, int id);
public Form1()
{
InitializeComponent();
} private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(ThreadMethod);
thread.IsBackground = true;
thread.Start();
} private void ThreadMethod()
{
string strName = "stemon";
int ID = ; while (true)
{
//lblResult.Text = DateTime.Now.ToString();
//这句话不能直接调用,因为子线程不能直接调用UI线程中的控件
if (this.InvokeRequired)
{
object[] myArray = new object[];
//类型的装箱是自动的
//类型的拆箱要强制转换
myArray[] = strName;
myArray[] = ID; this.BeginInvoke(new DoWorkUIThreadDelegate(DoWorkUIThread), myArray);
}
else
{
//DoWorkUIThread(strName, ID);
} //子线程还是可以访问UI线程的普通变量的,只是不能访问控件
//因为普通变量是属于整个类的,属于整个进程的,各个线程时共享的
//对访问共享的数据,加一个lock的锁更加的好
count++;
Thread.Sleep();
} } private void DoWorkUIThread(string name, int id)
{
txtTime.Text = name + " " + id + " " + DateTime.Now.ToString() + " " + count;
}
}
}
这个方法是这样操作的,BeginInvoke可以传递一个数组,这个数组是boject类型的,这样就可以把所有的参数都装箱成object类型的,弄成一个object类型的数组,然后到调用方在拆封就可以了。
[C#参考]主线程和子线程之间的参数传递的更多相关文章
- (转)C#/.NET主线程与子线程之间的关系
一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程. 有的博客上说“至少一个主线程”,这一说法持有怀疑 主线程与子线程之间的关系 ...
- C#/.NET主线程与子线程之间的关系
以前一直没有在程序中写过总结,再翻开程序时却不知所云,所以我决定写总结 一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程. 有的博客上说“至少 ...
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...
- Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解
MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android. ...
- Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息
MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import androi ...
- android 主线程和子线程之间的消息传递
从主线程发送消息到子线程(准确地说应该是非UI线程) package com.zhuozhuo; import android.app.Activity; import android.os.Bun ...
- 在C#主线程和子线程将数据传递给对方如何实现
在C#中主线程和子线程怎样实现互相传递数据 老帅 在C#中创建线程Thread时,能够有多种方法,而主线程和子线程之间又怎样实现互相传递数据,每种创建方法传递參数的效果是不同的,逐一看一下: 一.不 ...
- Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息
之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...
- Java并发编程原理与实战六:主线程等待子线程解决方案
本文将研究的是主线程等待所有子线程执行完成之后再继续往下执行的解决方案 public class TestThread extends Thread { public void run() { Sys ...
随机推荐
- C# base和this[转]
new关键字引起了大家的不少关注,尤其感谢Anders Liu的补充,让我感觉博客园赋予的交流平台真的无所不在.所以,我们就有必要继续这个话题,把我认为最值得关注的关键字开展下去,本文的重点是访问关键 ...
- C# 如何利用反射来加载程序集,并调用程序集中有关类的方法【转】
假设在C盘根目录下有个Dog的Dll程序集文件,该程序集文件中包含类Dog 该类中有个狗叫几声的方法,如何通过反射来加载这个C:\Dog.dll,并且调用Dog类里面的Sound方法呢: public ...
- vmware虚拟机迁移导致的eth0消失问题
将原来的ubuntu虚拟机文件迁移到还有一台机子之后. ifconfig显示仅仅有一个lo网卡,网上找了一些文章.大多是改动/etc/network/interfaces 原来内容是 # ###### ...
- C#DataTable学习心得
C#DataTable学习心得 一.DataSet.DataTable.DataRow.DataColumn 1] 在DataSet中添加DataTable DataSet.Tables.Add(Da ...
- Asp.Net之三层架构
三层架构之理论: 通常意义上讲的三层架构就是将整个项目应用划分为:表现层(UI),业务逻辑层(BLL),数据访问层(DAL).与传统的二层架构的区别在于在用户界面(UI)和数据库服务器之间,添加中间层 ...
- OC字符串的常用方法
网上写的关于字符串常用方法的博客很多,这里我简单做了下总结!不喜勿喷哦! 一.创建字符串 #import <Foundation/Foundation.h> //NSString //创建 ...
- iOS技术
iOS技术 OC:分类(好处,和延展的区别) 分类: 在不修改原有的类的基础上增加新的方法 一个庞大的类可以分模块开发 一个庞大的类可以由多个人来编写,更有利于团队合作 分类是对原有类的一种扩展,在 ...
- 关于sizeof()和内存对齐
PS补充:枚举类型的字节数为什么为4 百度知道回答: typedef enum e1{ MON, TUE, THI, }e; e1是一个数值,它的允许值范围是: MON,TUE,THI, 它的取值为其 ...
- 关于Condition Variable的一些思考
可能大家都使用过condition variable(之后称cv),一些博客也对cv做了介绍,但是有的说的不完全正确,甚至有误导使用者的倾向,其实最合理的使用方式是查阅文档, 如果你英语还ok的话,h ...
- Oracle学习之start with...connect by子句的用法
转自:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html,多谢博主分享 Oracle中start with…connect by ...