首页 新闻 会员 周边 捐助

不知不觉,已经到了线程这里,亲爱的,来聊聊线程吧。

0
[已解决问题] 解决于 2018-01-09 09:47
1)线程章节截图如所示
 
 
2)我的疑问是Thread  线程对象名  =  new  Thred(委托);
书中对这个委托的解释是要在新线程上执行的过程或者方法的名称。
据我所知,委托由delegate  关键字创建,可以传递方法,是一种特殊的引用类型,怎么到了这里成了一个名称而已?
这是何解? 什么时候委托仅仅成了一个名称,不再是传递方法,不再由delegate 关键字创建了?
绿绿山水的主页 绿绿山水 | 菜鸟二级 | 园豆:248
提问于:2018-01-08 10:05
< >
分享
最佳答案
2

先抛开委托的各种写法说下,对于一个thread而言,你肯定是希望通过某种方式告知这个thread要做什么,这个要做的东西最终在c#中体现为一段代码或者方法。

基于上述结论,我们肯定是希望将这段代码或者方法带入到thread中去,带入的方法这块在java中看起来更纯粹些也更直观些

先构建一个对象实现Runnable,并实现其中的run方法,run方法最终会被某个线程来进行调用

class MyTask implements Runnable

{

  @Override

  public void run(){

    //....we have a lot of work to do.

  }

}

接下来告知一个线程,这个task你来执行

Thread td=new Thread(new MyTask(),"wtf");

td.start();

通过这种方式就告知了thread你要做什么,那么在c#中实际上最后编译后也就变成这个模样了。但在实际写代码的时候c#比java要更进了一步,因为在前面构建的那个myTask对象除了告知thread要执行啥外没什么球用了,如果仅仅是写一两个倒没什么很大问题,但一般而言一个项目中要用起来会发现java的这种写法相当啰嗦而且极为蛋疼,那么我们希望有种更简单明了的方法来进行描述。

假设我们希望thread执行的方法为

class Mywork{

 public void LongRun(){.....}

 pubic void LongRun2(int count){...}

}

最直接的方式肯定希望是直接把这个方法带到thread对象中去,比如

var thread=new Thread(new Mywork().LongRun());

但这个时候你会发现这个LongRun一旦这样写了后(忽略语法错误)其表达的意义就是要执行这个方法了(而不是延后到调用Start时执行),而我们只是希望在这一步告知thread后面Start的时候要执行什么,所以这种表述很直接的方式是有问题的。那么我们需要在这个基础上变动下,我们希望告诉thread要执行的方法是这个或者说要执行的方法在这里,既然直接的方式不行,那么我们就需要一个中间人来支持下。

你可以看下Thread的构造函数的重载中有一个Thread(ThreadStart start)的方法,这种ThreadStart就是中间人,也就是委托,我们需要他来承载一个方法或代码块,这样就能避免前面出现的new Thread(LongRun())这种尴尬的错误了。

接下来的事就是我们需要这个中间人出来干活了,那我们就直接把要做的事塞给ThreadStart这个中间人即可

ThreadStart threadStart=new ThreadStart(new Mywork().LongRun);

Thread thread=new Thread(threadStart);

这里和更前面那种写法就是一个小括号的差异,而这个差异却体现了委托和普通方法的差异之一。更前面那种方式一旦写了(假设能执行的话)一旦执行后就会变成先执行LongRun方法,然后再构建Thread对象,而后面这种方式则是通过ThreadStart这个委托间接的告知Thread对象当你后面要跑的时候需要执行Mywork#LongRun方法。

当你弄清楚这种写法后会发现这种和java那种又臭又长的没什么区别吧,所以在编译器层面玩了点花样,然后你就可以写成

#省略构造ThreadStart对象(编译后还是会有的,只是书写更简单)

Thread thread=new Thread(()=>{

new Mywork().LongRun();

});

#再省一点(省略return,因为委托方法原型推断出来为ThreadStart,而ThreadStart这个委托是无返回值的)

var thread=new Thread(()=>new Mywork().LongRun());

#继续省略(省略构建Mywork对象,我们只是需要一段代码块而已,Mywork对象存在纯属多余)

var thread=new Thread(()=>{

  //...long run work here

  //...Thread.Sleep(1000);

});

到了这里c#相对java的语法/语法糖优势就充分体现出来了,当然这里不是说语法优势,只是通过java的语法告诉你其中的整个演变过程。

回到前面,我们将LongRun方法作为目标方法交给委托对象ThreadStart,那么你可以看下是否可以将Mywork#LongRun2方法也交给ThreadStart方法呢?

奖励园豆:5
Daniel Cai | 专家六级 |园豆:10424 | 2018-01-08 11:21

谢谢你。

ThreadStart threadStart=new ThreadStart(new Mywork().LongRun);

我不明白为什么要用new Mywork   ?   用Mywork不好吗?

就好比书中的Thread myThread = new Thread(new ThreadStart(myTask));

为什么ThreadStart 前面要加个new? 直接用ThreadStart 不好吗?

 

绿绿山水 | 园豆:248 (菜鸟二级) | 2018-01-08 17:03
其他回答(6)
0

只能说你对委托的认识不够,你的据我所知是对的,只不过你没转过弯,在这里,委托是系统已经定义好了,你只是调用而已。

~冰 | 园豆:509 (小虾三级) | 2018-01-08 10:18

我知道委托是可以调用的,在这里创建线程的过程中,调用了任意一个委托,作为了新线程的参数,对吧?

而书中解释的是方法的名称应该不对,()里面的是参数,而不是方法。

支持(0) 反对(0) 绿绿山水 | 园豆:248 (菜鸟二级) | 2018-01-08 16:21
0

1.委托的定义

1.1从数据结构来讲,委托和类一样是用户自定义类型

1.2从设计模式来讲,委托提供了方法的抽象。

1.3委托是类型,就好像类是类型一样。与类一样,委托类型必须在被用来创建变量以及类型对象之前声明。

delegate void MyDel(int x)。
2.Lambda表达式
MyDel del = delegate( int x) { return x; };//匿名方法
MyDel del2 = (int x) => {return x;};
Lambda表达式 MyDel del3 = x => {return x};//简写的Lambda表达式
3.委托再次抽象--func、Action
3.1Action用于没有返回值的方法(参数可以根据自己情况进行传递)
3.2Func恰恰相反用于有返回值的方法(同样参数根据自己情况情况)
3.3用法:
Action<string> BookAction = new Action<string>("函数名");
Func<string> RetBook = new Func<string>("函数名");

zouhp | 园豆:227 (菜鸟二级) | 2018-01-08 10:21
0

有些东西不要光看书,写个demo,打断点跟进看看源码更好

、熙和 | 园豆:1508 (小虾三级) | 2018-01-08 10:41
1

这里的“委托”是指委托类型的变量,myTask只是一个变量名而已

dudu | 园豆:30255 (高人七级) | 2018-01-08 13:13

勇哥:

ThreadStart threadStart=new ThreadStart(new Mywork().LongRun);

我不明白为什么要用new Mywork   ?   用Mywork不好吗?

就好比书中的Thread myThread = new Thread(new ThreadStart(myTask));

为什么ThreadStart 前面要加个new? 直接用ThreadStart 不好吗?

支持(0) 反对(0) 绿绿山水 | 园豆:248 (菜鸟二级) | 2018-01-08 17:05

@绿绿山水: Mywork与ThreadStart是类,new出来的是对象

支持(1) 反对(0) dudu | 园豆:30255 (高人七级) | 2018-01-08 17:15
0

新版的c#里有匿名委托,泛型委托,都不需要显式声明delegate关键字啦。

Eysa | 园豆:62 (初学一级) | 2018-01-08 14:59
0

还有豆不?

西漠以西 | 园豆:1675 (小虾三级) | 2018-01-08 15:18

选为最佳答案是有5个豆的。

支持(0) 反对(0) 绿绿山水 | 园豆:248 (菜鸟二级) | 2018-01-08 16:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册