博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c#多线程与委托(转)
阅读量:5358 次
发布时间:2019-06-15

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

一:线程

在.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); ///  /// 不带参数的启动方法 ///  public void NonParameterRun() { for (int i = 0; i < 10; i++) { Console.WriteLine("系统当前时间毫秒值:"+DateTime.Now.Millisecond.ToString()); Thread.Sleep(200);//让线程暂停 } } ///  /// 带参数的启动方法 ///  /// 让线程在运行过程中的休眠间隔 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 提供这个只是为了方便你编写,省得你自己再写一堆一样的委托了。

转载于:https://www.cnblogs.com/xihong2014/p/9132428.html

你可能感兴趣的文章
【svn】idea svn 文件上会出现一个破书
查看>>
cocos2d-x 3.0 场景切换特效汇总(转)
查看>>
The SortedMap Interface
查看>>
SniperOJ-leak-x86-64
查看>>
bzoj 4260: Codechef REBXOR (01 Trie)
查看>>
学好python
查看>>
css-IE中的border-radius和box-shadow
查看>>
利用bootstrap和webform的异步CRUD及分页
查看>>
HDUOJ 1879继续畅通工程(并查集)
查看>>
OC12_自动释放池
查看>>
Saiku资源帖
查看>>
解决手机页面中点击文本框,网页放大问题
查看>>
2-5
查看>>
牛客多校3 A-PACM Team(状压降维+路径背包)
查看>>
HDU - 4284 Travel(floyd+状压dp)
查看>>
1027 制作表格
查看>>
Android之Socket通信、List加载更多、Spinner下拉列表
查看>>
面向对象的介绍与特性
查看>>
typing-python用于类型注解的库
查看>>
20189215 2018-2019-2 《密码与安全新技术专题》第13周作业
查看>>