c#多线程与委托(转)
一:线程
在.net中提供了两种启动线程的方式,一种是不带参数的启动方式,另一种是带参数的启动的方式。
不带参数的启动方式
如果启动参数时无需其它额外的信息,可以使用ThreadStart来实例化Thread:
带参数的启动方法
带参数,就不能用ThreadStart委托作为构造函数的参数来实例化Thread了,而要 ParameterizedThreadStart委托,和ThreadStart一样的是它也是线程启动时要执行的方法,和ThreadStart不同 的是,它在实例化时可以用一个带有一个Object参数的方法作为构造函数的参数,而实例化ThreadStart时所用到的方法是没有参数的。 为 什么是Object这样的参数呢?很简单,因为在.net中Object是所有类型的基类,用它可以表示Array(数组)、Interface(接 口)、ValueType(值类型,如bool,byte,char,short,int,float,long,double等)、class(类) 等.net中的类型。当然,这也意味着如果你要启动一个线程,给它传递一个int类型参数时,必须在启动方法中进行相应的类型转换。
这种object类型的参数可以定义一个有多个属性的类来进行,或者用$隔开的字符串,使用的时候分解为数组来用
简单实例代码:
//不带参数
ThreadStart ts = new ThreadStart(ThreadFunc);
Thread t = new Thread(ts);
t.Start(); //带参数
ParameterizedThreadStart ParStart = new ParameterizedThreadStart(GoTo);
Thread myThread = new Thread(ParStart);
object o = (object)txt_url.Text;
myThread.Start(o);
详细实例代码:
Program p = new Program();
Thread nonParameterThread = new Thread(new ThreadStart(p.NonParameterRun));
nonParameterThread.Start(); Thread parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));
parameterThread.Name = "Thread A:";
parameterThread.Start(30);
/// <summary>
/// 不带参数的启动方法
/// </summary>
public void NonParameterRun()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("系统当前时间毫秒值:"+DateTime.Now.Millisecond.ToString());
Thread.Sleep(200);//让线程暂停
}
} /// <summary>
/// 带参数的启动方法
/// </summary>
/// <param name="ms">让线程在运行过程中的休眠间隔</param>
public void ParameterRun(object ms)
{
int j = 10;
int.TryParse(ms.ToString(), out j);//这里采用了TryParse方法,避免不能转换时出现异常
for (int i = 0; i < 10; i++)
{
Console.WriteLine(Thread.CurrentThread.Name+"系统当前时间毫秒值:" + DateTime.Now.Millisecond.ToString());
Thread.Sleep(j);//让线程暂停
}
}
二:委托
委托就是讲方法以参数的形式进行传递
private static void WriteStrToFile(string txt)
{
write(txt);
}
private delegate void WriteStrToFileDelegate(string txt);//定义委托
new WriteStrToFileDelegate(WriteStrToFile).BeginInvoke(txt, null, null);//异步使用委托
再举一例:
public delegate void GreetingDelegate(string name);//定义委托 //定义两方法
private static void EnglishGreeting(string name)
{
Console.WriteLine("Morning, " + name);
} private static void ChineseGreeting(string name) {
Console.WriteLine("早上好, " + name);
}
使用:
private static void GreetPeople(string name, GreetingDelegate MakeGreeting)
{
MakeGreeting(name);//这里默认同步方式,与MakeGreeting.Invoke(name)效果一样
} //使用
GreetPeople("Jimmy Zhang", EnglishGreeting);
GreetPeople("张子阳", ChineseGreeting);
实际上,我们可以也可以绕过GreetPeople方法,通过委托来直接调用EnglishGreeting和ChineseGreeting:
GreetingDelegate delegate1;
delegate1 = EnglishGreeting; // 先给委托类型的变量赋值
delegate1 += ChineseGreeting; // 给此委托变量再绑定一个方法
// 将先后调用 EnglishGreeting 与 ChineseGreeting 方法
delegate1 ("Jimmy Zhang");
Console.ReadKey();
委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量IO操作),可能会让程序停顿很长时间,造成糟糕的用户体验,这时候异步调用就很有必要了。
异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
委托的异步调用通过BeginInvoke和EndInvoke来实现。
比较:
在实例化Thread的实例,需要提供一个委托,在实例化这个委托时所用到的参数是线程将来启动时要运行的方法。
委托其实也是一个线程
MethodInvoker mi = new MethodInvoker(DoPay);//定义委托
this.BeginInvoke(mi);
这里MethodInvoker
只是一个委托, 我们可以认为所有没有参数的返回值为void的委托和 MethodInvoker 是一样的, 他们都可以委托到没有参数的返回值为void的方法。
你自己写一个 Public Delegate Sub ABC, 这个时候ABC和MethodInvoker是完全一样的。所以.Net 提供这个只是为了方便你编写,省得你自己再写一堆一样的委托了。
c#多线程与委托(转)的更多相关文章
- BeginInvoke与EndInvoke方法解决多线程接收委托返回值问题
BeginInvoke与EndInvoke方法解决多线程接收委托返回值问题 原文:http://www.sufeinet.com/thread-3707-1-1.html 大家可以先看看我上 ...
- WinForm多线程及委托防止界面假死
当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决. using System; using System.Collections.Generi ...
- 多线程、委托、Invoke解决winform界面卡死的问题,并带开关
一.知识点介绍 1,更新控件的内容,应该调用控件的Invoke方法. Invoke指: 在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托.该方法接收一个委托类型和委托的参数,因此需要定义 ...
- [小工具] C#多线程|匿名委托传参数|测试网站压力--升级版
上次文章链接:http://www.sufeinet.com/thread-11-1-1.html写这些并不是不会用测试工具,也并不是无视测试工具,而是做为一个程序员希望用自己写的东西来完成一些功能, ...
- WinForm中 事件 委托 多线程的应用
WinForm中 事件 委托 多线程的应用[以一个下载进度条为例] 第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就 ...
- WinForm多线程+委托防止界面假死
当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Generic ...
- WinForm中 事件 委托 多线程的应用【以一个下载进度条为例】
第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体 在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就开始下载 下载完成后 在注册窗体上面 显示下载完成(达到在一个窗体 ...
- C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate 转载
问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界面,使用一个子线程来执行程 ...
- WinForm多线程+委托防止界面卡死
1.当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Gener ...
随机推荐
- 3-log4j2之输出日志到文件
一.添加maven依赖 <dependencies> <dependency> <groupId>org.apache.logging.log4j</grou ...
- python-tornado和django优缺点
Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使用起ORM,做简单的定义,就能自动生成数据库结 ...
- PAT 乙级 1066. 图像过滤(15)
图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换. 输入格式: 输入在第一行给出一幅图像的分辨 ...
- Kesci: Keras 实现 LSTM——时间序列预测
博主之前参与的一个科研项目是用 LSTM 结合 Attention 机制依据作物生长期内气象环境因素预测作物产量.本篇博客将介绍如何用 keras 深度学习的框架搭建 LSTM 模型对时间序列做预测. ...
- 【转载】 程序员制作996.icu网站抗议加班,你认为996能提高工作效率吗?
原文地址: https://zhidao.baidu.com/question/623053193192988612.html ------------------------------------ ...
- 【leetcode】344. Reverse String
problem 344. Reverse String solution: class Solution { public: void reverseString(vector<char> ...
- SDM(Supervised Descent Method and its Applications to Face Alignment )
sdm SDM 人脸对齐的核心内容很简单,就是特征到偏移量的映射: Ix = R I 是特征,x是映射矩阵,R是偏移 ...
- MySQL中的修改表操作
一.增加表的列 语法:alter table 表名 add( 增加列定义 ); 实例: #增加列 alter table text add( text_num ) ...
- AI之路,第二篇:python数学知识2
第二篇:python数学知识2 线性代数 导入相应的模块: >>> import numpy as np (数值处理模块)>>> import scipy ...
- 九度OJ1108-堆栈的使用
题目1108:堆栈的使用 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:11620 解决:3372 题目描述: 堆栈是一种基本的数据结构.堆栈具有两种基本操作方式,push 和 pop.P ...