msdn 访谈录之C#编程二

c# 专栏收录该内容
11 篇文章 0 订阅

程序员天地

Robert Hess和Jeffrey Richter(著名的编程作家、专栏作家和咨询专家)的谈话。


ROBERT HESS: 欢迎回来。我们正要涉及到有关C#编程方面的问题。为了有助于我们理解这些问题,我邀请我的好朋友Jeffery Richter到这里来。Jeffery恰好是一名撰写了很多编程书籍的程序员,他最新的一本书为Programming Server Side Applications for Windows 2000。现在您也是一位咨询专家并且拥有自己的公司Wintellect,是吗?

JEFFREY RICHTER: Wintellect。

ROBERT HESS: 我猜您有一个网站吧?

 

JEFFREY RICHTER:有,Wintellect.com。我们专门从事培训、调试和广告。

ROBERT HESS: 好了,我了解到您最近做了不少有关C#的工作。

 

JEFFREY RICHTER: 是的,至今已一年有余了,我花了很大的精力一直专攻C#的编程。

ROBERT HESS:已经有一年了?我想我们才刚发布了C#。

JEFFREY RICHTER:是的,可我一直在圈内,在Microsoft的圈内,如果您愿意的话。我自己在第42楼安置了一个小小的办公室,并在那里从事C#的研究和有关.NET这方面的工作,到现在已经一年多了。

ROBERT HESS: 这样微软就会对您有所帮助,因为您并不是微软的职员……

 

JEFFREY RICHTER: 对。

ROBERT HESS:他们只是帮助您的把C#当成一种语言理解,那么您就可以写出更多象这样的书?

JEFFREY RICHTER:是的,他们希望我写更多的书,我得到了帮助,发现了bug,出席了类似的一些规范会议,并与人们交流,因此我觉得学到了很多的东西,而不只是写书,而事实在某种程度上也对C#做出了贡献。所以我可以告诉您,当最初开始时,我感兴趣的第一个东西就是这种新的语言,我将用它来写所有的代码,我知道这些代码是为可以预见的未来写的,让我们暂且不提。我具有非常深厚的C、C++背景,在阅读与C#相关文档和编程参考等资料一个星期之后,我就觉得已经相当精通C#了。并且在一周之内,我能够真正地写出一些有用的东西。

 

ROBERT HESS:仅仅一周之后。

JEFFREY RICHTER:是的,仅仅一周之后。因为它和C++非常类似,您知道,那里的大括号是相同的,返回值是相同的,参数是相同的,许多东西都是相同的。

ROBERT HESS:当继续使用对象、析构函数、构造函数、双冒号(::)等这些老掉牙的东西时,您似乎就要失去他们所拥有有的某些奇特的命名习惯,对吗?

JEFFREY RICHTER:是的是的,双冒号(::)都被点号(.)代替,箭头号(->)也被点号代替,这样就大大地简化了该语言。因而对于我来说实在是太容易啦,而且它还具有时效性,我仍不得不回过头去查看该语言参考资料,或许查找如何重载运算符,或者某些很平常的东西,要知道,当我编程时,极少做一些模糊不清的事。而现在大多数东西对我来说是再自然不过的了。事实上要解决的只是流程问题。

ROBERT HESS:既然您从事这项工作已经一年多了,那么您注意到了在这段时间里这种语言自身的演变吗?是否它们今天仍然与一年以前的十分相同?

JEFFREY RICHTER:我认为十分相同。但肯定存在着一些小技巧(tweak),在beta测试阶段确实存在着这些回应,存在着许多非确定性的析构函数(non deterministic destructor)、对象的析构(destruction of objects)等类似的东西。因此,基类库已经增加了一个iDisposable接口,我想它将会出现在beta 2.0版中,而不是在beta 1.0版中。同时C#已增加了一些新的语言结构,以帮助你获得与对象的确定性析构(deterministic destruction of objects)关系密切的东西。所以我要说,微软已经十分在意人们对该语言的评价了,并且他们还企图在其中加入新的东西以做出回应。我同样了解到,将来在1.0版之后,他们计划要增加泛型(generics),这有点类似C++中的模板,而我可以肯定,为了支持这些性能,C#就要发展。实际上当处于公共语言运行库(common language runtime)之中时,所有的语言都能用到泛型。

 

ROBERT HESS:因为它们是其中的一部份,又因其是公共语言运行库,所以它们有权使用所有的那些功能。那么您认为,C#作为一种语言总的来说究竟怎么样?

JEFFREY RICHTER:嗯,正如我所说的,C#与C++非常相似,所以我很快便熟悉了。它非常非常的干净,我要说它是非常干净的。我出身于C++背景,尤其是作为一个Windows C++程序员。ANSII拥有C++规范,微软为了展示Windows中的功能,就想在C++中保留一些技巧,并且使这些技巧看起来有点像C++中的贵族,可它们从来就没有真正地达到要求。而微软仍陆续增加__try、  __finally 和 __declspec等类似的东西。

ROBERT HESS:这就是您正在谈论的C#。

JEFFREY RICHTER:对,当然还有C++。因此,这种语言确实有点恐怖,过了一会儿您还是不会完全弄明白,就如const的用法,当声明一个指针或者是一个常量指针时,星号(*)究竟应放在它的前面,还是放在后面?您将无法断定这些修饰符到底应放在该行的那个位置。我总是需要查资料。因此在C#中,由于微软在设计时已经预先向ECMA(欧洲计算机制造商协会)做出了要求标准化的提议,所以它实在很干净,例如,没有什么是以下滑杠开始的。当然,由于本来在.NET runtime中就没有真正的指针,所以在您的代码中,从头到尾都不会能见到*号和&号等此类修饰符。这样当考虑它时,看起来干净,真的觉得很爽。

 

ROBERT HESS:难道您不觉得缺少什么吗?我的意思是,当我在用C编程时,喜欢运用指针解决问题,对指针重新分类,利用指针算法等老掉牙的东西,您就会从中获得极大的乐趣。难道您在用C#时就不怀念它吗?

JEFFREY RICHTER:嗯,我不得不承认,我自己总是有些喜新厌旧,但有时也有点念它。当然总的来说,有了C#和.NET framework,您就可以始终与其它语言进行交互操作(interoperate out),因而如果真的必须那样做的话,我便用C++而不是C#编程了。C#也确实提供了一种不安全的关键词(unsafe keyword),这样一来,您就可以创建一个方法并且说,这是不安全的,您有权使用指针并对内存进行直接操作。尽管如此,我还是从未亲自体验过。至于编码时获得的乐趣,.NET framework和基本OS类库提供了大量的特性,它们使编程变得有趣了。因此,当我不能保留虚拟内存并稀疏地提交,也不能在.NET framework中利用内存映象文件进行工作时,至少不能直接进行时,也可以通过交互操作完成,仍然还有其它类似serialization和web服务等东西,它们有利于创作出真正有价值的应用程序,真正强大而丰富的内涵。

ROBERT HESS:如今在您的培训班里,您正在教授和灌输这样的东西,您还在办C#的培训班吗?

JEFFREY RICHTER:是的,事实上刚好这一周,我给第一个C#编程班上课,当时班里有两个Visual Basic程序员,他们根本就不是面向对象的程序员,而我也没有真正地给他们介绍过C#语言,因为我把重点放在公共语言运行库和基类库方面,有关C#的内容想稍后再讲。但是,这两个VB程序员在上机实习时,对C#上手很快,几乎没有遇到什么麻烦,而且竟然能用其进行开发,效率也高。我十分惊讶!

ROBERT HESS:其中的原因是由于在C#中,您使用name.name.name.name,而不是name、->、name.name、-> name.*、*、()、&等老掉牙的东西……

JEFFREY RICHTER: 确实这样。

ROBERT HESS:这些在VB中都不会用到。

JEFFREY RICHTER:正确。

ROBERT HESS:所以格式看来相当一致。

JEFFREY RICHTER:对,相当一致。当然,他们用大括号{}而不是begin和end,这可能使有些人不适应。但我认为,他们最多花不到5分钟的时间就可以克服它,而且更多产。

RROBERT HESS:那么以一个公司的立场,假如一个公司聘请您去开设一个C#培训班,因此我得去发现他们是否开始考虑把公司的一些成果移植到C#,这就是您建议他们要做的事吗?或者您认为他们应处于哪一个阶段?

JEFFREY RICHTER:嗯,当然它取决于,首先他们必须决定是否要采用.NET framework作为开发平台。我认为这非常有价值,对于我来说毫无问题,那是我真正向往的平台。如果您正在开发.NET framework的应用软件,正在编写新的代码,在我看来会不费吹灰之力。 C#上手实在是很容易,它是一种生机勃勃的语言,使用正确的方法您会非常多产的。我个人也相信大量的VB程序员,VB6.0程序员,将会转向C#而不是VB7.0。

ROBERT HESS:那为什么?

JEFFREY RICHTER:因为我认为C#揭示了公共语言运行库(common language runtime)之中的更多的特性,使您对代码及其所表达的方法具有更多一点的控制权。您将更直接地与runtime对话,runtime赋予了您更多的权力。

ROBERT HESS:当然,我们本身谁都不是VB程序员,所以将明确地在C基础之上发展。

JEFFREY RICHTER: 您是对的。

ROBERT HESS:所以这正是它物有所值之处,我们有点偏离正题了。那么作为一种语言,您喜欢C#的哪些方面呢?是更简单、更彻底(clean)的编程吗?

 

JEFFREY RICHTER: 嗯,主要是去掉了无用的东西。 譬如, 嗯, C#不允许您把参数作为常量(const)声明,并且您不能拥有一个const的实体方法,而在C++中则可以。我知道某些人会认为那样会真的丧失语言的特性,但事实在C++中,const总是会被无情地抛弃,这样您就能在自己的代码中为所欲为了。由于C#实在是不允许您使用const,所以它又彻底又易于理解。现在,我想我应该说:对于我,.NET frameworks真正有趣的东西就是公共语言运行库。它定义对象如何运转,或如何创建类型,以及是什么定义了这些类型的行为。这样您就拥有了一个基类库,当然它是一个巨大的类库,它让您有权使用大量的东西,所以即使您愿意,也不必再三重写每一样东西了。您选择语言是您个人的事情,而我选择了C#是由于它是真正优秀的高阶语言,它让我能与framework对话。但在某种程度上,运用.NET runtime和基类库真正最佳的语言应该是中间语言(immediate language)汇编语言。

ROBERT HESS:哈!谈到汇编语言啦?

 

JEFFREY RICHTER:是的,谈到汇编语言了。我的意思是,它使您完全有权访问平台的底层,但在汇编语言的环境中效率会很低,有这么多的程序您必须一行一行地写。所以,C#语言高出了一个层次。而在C#中的有些性能并不是很常用,因此象Anders 这样的C#设计者已决定不必将其公开了。在某些情况下,为了访问C#没有提供的runtime功能,我可能会求助于另外一种语言。但总的来说,C#是最高层的语言,它允许我在这样的环境中按自己的需求解决大量的问题,而且效率极高。

 

ROBERT HESS:并不是所有的问题,而仅仅只是大部份?

JEFFREY RICHTER:不,极少会出现这种情况:我还需要访问某些东西,而C#却不让访问。这是另外一方面,我只是认为大家非常容易忘却的是,当您想要访问.NET的一些功能而C#或某些语言却不提供给您时,可以转到别的语言。只需编码创建这个方法,可能是一个静态方法(static method),类中的静态方法,用APL或COBOL或凡是您选择的语言,或许派生,然后用某些语言实现实体方法,而这种语言可能真的让您访问某些底层功能。因此,我认为这是一个功能非常强大的范例,以前我从未真正地领会过要选择最佳的语言去完成工作。

 

ROBERT HESS:好了,我打赌各位观众可能想要看一些C#代码的例子,以便能理解我们谈论到的一些问题。您有例子示范给我们看吗?

 

JEFFREY RICHTER:有。我确实的带来了一个源代码文件,里面有一些例子,能勉勉强强地应付,在节目结束后,我会给您的。欢迎您把它上传到网站上,以让大家可以下载。所以在这里,如果你样喜欢的话,我首先要示范的是:在C#中,每一个方法必须位于类中。没有全局方法,也没有位于类之外的变量,所以每一样东西都会被限定在一定的范围内。
using System;

 

class App {

   public static void Main () {

      Console.WriteLine("Hello World");

   }

}

这是一个必须保留的hello world程序,非常简单。在程序里,有一个类叫App,在这个类里,我拥有自己的一个Main方法,并且Main是一个静态方法,因为它必须从外面调用。我们不必拥有App的一个实例就可以调用Main。在我这个例子里,Main返回void,并且没有接受参数。简单地在Main的内部,它调用了Console.WriteLine,在显示器上面显示出"Hello World"。所以这是您可以写的、能学到相关概念的最小程序了。

 

ROBERT HESS:在C#中Main仍然是一个保留的方法吗?就象在C++中?

JEFFREY RICHTER: Main是默认的,它具有大写字母M,小写字母a-i-n ,因为C#是字母大小写敏感的语言,象C++ 而不象VB 和.NET 。所以当编译器编译代码时,将寻找一个叫做Main的静态方法,然后再使用它。然而有一个编译器的命令行,它可以覆盖掉Main并选取其中不同的一个。顺便说一下,事实上这是一门很有用的技巧。一些人把多个Main放到一个单个的应用程序里,以便进行组测试,当编译时,可以设置不同的开关执行不同的Main,以便测试特定的组件。

ROBERT HESS:绝妙的技巧。您也使用象argv、 argc这样的参数,默认地传递给Main函数吗?

using System;

 

class App {

   public static void Main (string[] args) {

      Console.WriteLine("Hello World");

   }

}

 

JEFFREY RICHTER:是,随您的便。在这里,我将当场修改这些代码,也就是说,string是一个字符串数组,args 按我在幻灯片中播放的定义。顺便地,这个args是什么呢?是一个数据类型!它是一个指向字符串的指针,或者是一个指向字符串的引用。说到指针,您只见过带*号的,但args确实是一个指针。当Main被调用之前,启动代码早已解析命令行,并且创建一个字符串数组,接着把指针传入该数组。象对args.length类似的调用使我可以解决一些问题,该调用会返回数组的length属性,此属性含有数组元素的个数,然后我正好可以利用一个正常的for语句进行循环,或者可以用C#的for each,特殊的for each语句用于快速的循环。

 

ROBERT HESS:很新颖,这是在C或C++中所没有的。

JEFFREY RICHTER:正确。而我确实也有演示的代码,我找到了。

static void ArrayDemo() {

   // 声明一个指向数组的引用

   Int32[] ia; // 默认值为 null

   ia = new Int32[100];

   ia = new Int32[] { 1, 2, 3, 4, 5 };

   .

   .

   .

这是一个具有数组的代码的例子,所以我会略为提一下。在这个例子里,首先声明一个指向Int32s数组的引用,随意取一个"ia"用于整数数组。它只不过是一个指针,具有32位(bit)或64位值,如果它们仍在64位系统上运行,总是会被初始化为null,引用总是被初始化为null直到明确地设置它为止。下面一行,我随意new(构造)了一个有100个Int32值的数组。new返回一个引用,接着我把这个引用存到"ia"变量中。下一行只不过演示了另外一种构造的方式,这里我又new了一个Int32s数组,这种专门的C#句法以一个左大括号开始,后面跟着数组的元素,当然元素之间要用逗号分开,然后是一个右括号。当您第一次见到这种句法时,会觉得它有点笨拙。这只不过是new的另外一种用法,当然它可以推算出元素的个数。


ROBERT HESS: 而这只不过是预定义了值:

   .

   .

   .

   // 显示数组的内容

   foreach (Int32 x in ia)

      Console.Write("{0} ", x);

 

 

   //使用多维数组

   StringBuilder[,] sa = new StringBuilder[10][5];

   for (int x = 0; x < 10; x++) {

      for (int y = 0; y < 5; y++) {

         sa[x][y] = new StringBuilder(10);

      }

   }

 

   // 使用数组的数组(jagged arrays)

   Int32 numPolygons = 3;

   Point[][] polygons = new Point[numPolygons][];

   polygons[0] = new Point[3]  { ... };

   polygons[1] = new Point[5]  { ... };

   polygons[2] = new Point[10] { ... };

}

 

JEFFREY RICHTER:是的,很正确。这就是foreach,它出现在代码的第一行。"foreach"是C#句法,我肯定所有的.NET语言都会提供此句法,它是一个极其通用的编程典范,用这种方式,就可以遍历集合里的元素。因此,这里的foreach Int32 x中,"x"是一个变量,Int32当然是一种类型,接着我把引用赋予了数组。foreach将会自动推算出数组中有多少个元素,并且每当循环到Console.Write时,就会显示出元素的值,然后再移向下一个元素。


ROBERT HESS:而"for (i=0, i<ia.length, i++)"也做同样的工作,但如果您想要遍历所有的元素的话,这种方式有些笨拙以至难于遵循,所以一直持续不断地做十分相同的事情,我想会更加容易。


JEFFREY RICHTER:对,精辟。尽管如此,我会给您一点提示,由于foreach有点酷,也十分精巧,因此省去了大量的编码。它也另外做一些有关类型转换(casting)的工作,这对您同样也有好处。所以一般来说,当我写一个循环时,我通常会以foreach开始,然后当我继续编码时,有时经常地,我随后认识到我需要一个迭代器(iterator),需要一个从0到实际数字的X。是的,我必须知道哪一个元素号。所以我终止了重写这个循环,相当频繁……


ROBERT HESS: 噢,真的吗?


JEFFREY RICHTER: 是真的。

 

ROBERT HESS: 当作一个标准的For循环?

 

JEFFREY RICHTER:对,当作一个标准的For循环。因此有时到了最后,它所做工作比我当初想象的还要多。使用foreach是相当常见的,有了它实在是很爽。


ROBERT HESS:我猜您本来也应当在那里放置一个计数器,不过这会完全使foreach不起作用。


JEFFREY RICHTER: 是的,很正确。

 

ROBERT HESS:那么,您认为C#还另外具有什么样很酷特性,以让观众说,好,这就是我要选的语言?


JEFFREY RICHTER:嗯,正如Anders在前面指出,C#是完全基于组件的,在那里具有事件,具有接口,具有属性,它们都是一等公民,所以没有下滑杠,没有下滑杠属性等任何类似的东西。出身于C#的人应当熟悉异常处理,因为遇到错误时,就调用在基类库中的framework里的错误处理程序。因此我在屏幕上写了一小块代码,以示范如何进行适当的错误处理。我具有一个try语块,再强调一下,您应注意在try这个单词的前面没有下滑杠,因为在C#语言中它位于第一阶层。我new一个文件流对象,这是打开磁盘里的文件的一种方式。而在双引号里,我给出了我们希望打开的文件的路径名。

using System;

using System.IO;

 

public class App {

   public static void Main () {

      FileStream fs = null;

      try {

         fs = new FileStream(@"C:/NotThere.txt", FileMode.Open);

      }

      catch (Exception e) {

         Console.WriteLine(e.Message);

      }

      finally {

         if (fs != null) fs.Close();

      }

   }

}

 


ROBERT HESS:等等,那是一个错误,是吗?

 

JEFFREY RICHTER:不,这正是我要指出的。因为C#有一个非常酷的特性,可以给字符串加上一个@符号的前缀,使我们转用原义字符串(verbatim  string,即真正的字符串,不加任何转义符),这里只允许使用单反斜杠“/”而不是双反斜杠“//”。而长路径实在是一种十分常见的C++编程错误,人们以反斜杠代替双反斜杠,文件就不能正确地打开。在这种情况下应用加上"/n",意思是要换行。所以,这实在是一个巧妙的特性。不象一个file stream,因为人们熟悉Win32的CreateFile函数,当该函数无法打开一个文件时就会返回无效的句柄值,或返回-1意味着失败。在.NET framework中,当我企图打开一个不存在的文件时,就会引发一个异常,所以我在这里设置了一个catch语块,设法捕获到异常,这是一个非常简单的catch语块,只把信息输出屏幕,看看可能做了些什么,接着我又设置了一个finally语块,在这里的代码要确保能执行,因此假如我在try语块中有很多行真正涉及到文件操作的代码,在打开文件之后,finally语块就会执行并在最后明确地关闭文件。这实在是一种很巧妙的特性,Win32甚至是C++也不曾拥有,它能够使try,catch和finally浑然一体,真正算起来,这种操作我们以前从未遇见过。


ROBERT HESS:我认为当应用程序变得越来越复杂时,人们在其中进行错误处理是相当重要的,当企图创建文件或进行类似的操作时,出错的机会可能会很多。尤其是使用其他人的对象和类似的东西时。
    那么,这是不是意味着在编写C#的应用程序时,您必须保证函数和方法都能正确地设置异常并抛出一个异常,以便人们可以捕获它?
 

JEFFREY RICHTER:嗯,绝对如此。良好的编程典范规定:当编写一个函数时,必须验证所有传递进来的参数,如果任何一个参数不合乎要求,就应当明确地引发一个异常,而在基类库中定义有大量的异常类,所以可以轻而易举地使用其中的一个。但是您同样也有能力定义自己的异常类,或许,要查找数据库中的、顾客(customer),却好象没有发现他们的名字,故可以创建自己的customer异常,并在代码里的某个地方引发它。

ROBERT HESS:或许会用类似customer的名字作为损坏的customer名……


JEFFREY RICHTER:是的,大概这样。如果它是"Robert",就是你一直想要引发的异常。

ROBERT HESS:那么,您认为C#作为一种编程语言将如何发展?当您的客户参加培训时您对他们有什么点拨,他们对此又有什么想法?

 

JEFFREY RICHTER:嗯,我真的认为它将获得巨大的动力。我说过,去年我一直专门用C#编程,偶尔也用C++,但现在却很少用了,而我相信许多VB程序员也将会转向此语言,因为C#更适合公共语言运行库。所以,我真的认为它将获得巨大的动力,并且真正得到重用。在我的培训班里,似乎每个人都喜欢它,事实上一些人说他们参加这个培训班,只是由于这个班开设了C#编程的课,但很快他们就高兴地发现课程也涵盖了framework和类库。

ROBERT HESS:那么,当谈到.NET framework和类库时,您认为它们怎么样,以及它们是怎样帮助应用程序开发的?

 

JEFFREY RICHTER:我认为,这个平台表现很出色。我使用整个平台已经一年了,并且我最近一直在为微软开发一个项目,以展示微软的许多技术。我和另外一个家伙一起工作,他的名字叫Tom,我们要在早上碰头,要在电子白板上继续讨论,接着要…… 这里就是我们今天将要补充说明的性能,我们又要讨论一会儿,我们要表示,这就是当天结束时我们的目标,通常在午饭之前我们要全部完工。我们总是超额地完成了任务。

 

ROBERT HESS:您认为C#和.NET的结合有助于完成工作吗?


JEFFREY RICHTER: 噢,当然。毫无疑问,因为所有的测试都已完成。所有的测试——我们如何公开这个东西,我们能不能使这成为一个方法,能不能把它放在DLL里,能不能使其成变COM 对象,我们应拥有什么类型的接口。所有的这些问题涉及到您如何把这些连接起来并传递指针,保持连接以便可以同步,所以您就可以通过保持和其他人同步来通知他们,所有这些论点都刚刚被引进该平台。因此,自始至终地,我们愿意工作一个小时,我们要完成某项工作,我们会……,然后我们又要坐回去并开始增加其它的东西。我们的生产率如何,确实令人难于置信,而且也同样充满着乐趣。我们确实增加了惊人的图形图像库和alpha混色(blending)以及所有类型的东西,这些以前我们从未处理过alpha混色此类东西。我曾经从事过图形图像的工作,但已经过了好多年了。而利用相应名字空间中的system.drawing语句,我们就能够构造这些图像并对它们进行覆盖和alpha混色,然后又从我们的web服务器返回这些图像给在任何机器上运行的任一客户,甚至不必是一台Windows机器。


ROBERT HESS:我想这带来了有利的选择。迄今为止,我们一直在谈论用C#和.NET framework等进行应用程序的开发,并且我了解到您原来就是一个货真价实的应用程序设计师,编写Windows应用程序和标准的GUI程序。令人意外的是web出现了,因此每个人都想到编写web应用程序,或编写运行在浏览器内部基于HTML的应用程序。但现在以一句话对您的产品进行概括,您正在谈到具有这种alpha合成标准的Windows图形应用程序,也谈到了访问web并以相应的格式返回给其它系统。那么象您我这样的Win32应用程序开发者,对传统的应用程序开发环境以及新的web应用程序与.NET的混合有什么看法?

 

JEFFREY RICHTER:嗯,我实际上在做的就是这种特别的事情,它不是Win32图形应用程序,而是一个web窗体(form),随意一个web窗体。
ROBERT HESS:那么它甚至也不是一个传统的Windows应用程序吗?它听起来很象啊。
JEFFREY RICHTER:嗯,它真正是什么?实际上它比传统的Win32程序具有更复杂的体系。它实际是一个web服务,并且我认为它是第一批公用微软web服务(public Microsoft web services)之一,是免费的,所以我会给出URL地址。因此谁都可到那里去摆弄摆弄,这个地址是teraserver.Microsoft.net。
ROBERT HESS:噢,我会把这个地址放在本记录稿的后面,以便大家点击访问。

JEFFREY RICHTER:那里有许多微软技术的广告宣传,其中包括Windows 2000 Datacenter、SQL 2000、IIS、ASP.net、.NET frameworks、web services和web forms。所在的资料都在那个网站上。有一个具有图像信息的teraserver web服务,它显示立体地形图和常规像片里的图像和标题。而且我们也有一个人口普查(census)服务,所以可以到那里输入纬度、经度等,便得到相应的城市名以及生活在该地区的人口。我们还有地标(landmark)服务,给出一个以经纬度标定的矩形区,就可以找到该地区范围内的医院和学校。因此,它们是三个单独的web 服务。它们本来可以由不同的公司实现,但实际上都是由我们实现的。接着我们编写了一个web窗体应用程序,它本来可以由任何公司编写,但这次又由我们编写,以便弄清概念,它向这三个不同的web服务发出信息,接着从teraserver获取标题信息,从landmark服务器获取地标信息,然后我们就能够把这些信息载入地图。

 

ROBERT HESS:使用alpha混色。

JEFFREY RICHTER:嗯,对,使用alpha混色。于是,这些信息被送回web窗体,送回运行在任何机器上的客户。我们甚至可以增加这样的功能,当鼠标移到某东西上方时,提示工具将会显现并告诉您该网页上相应的学校名和医院名。此范例功能之强大,简直令人无法相信。事实上客户可以是运行任何操作系统的任何机器,并且我们在服务器端利用Windows 2000的GDI+性能处理alpha混色,以及此类高级图形操作,不过我们只把位图(bit map)送回给客户,我再次认为,其功能之强大、生产率之高,简直令人信难于置信。而且我也了解到许多应用正在朝这个方向发展。

ROBERT HESS:所以您真的很喜欢web应用程序的整个web模型。
JEFFREY RICHTER: 喜欢。

 ROBERT HESS:即使您是一个传统的Windows应用程序开发者。
JEFFREY RICHTER: 是的。

ROBERT HESS:您现在已横下心来要朝这个方向发展了。

 

JEFFREY RICHTER:是的,我已下决心了。程序要能在任何地方运行,并在服务器上进行工作。所有的这些便构成了所谓的分布式系统(distributedness),服务器可以位于三台不同的机器,噢,维护所有的这些资料的SQL Server还可以是另一台机器,web 窗体服务器也位于不同的机器,并且还可以被不同的公司细调以便随意使用这些材料,他们觉得这些材料适合于生成内容丰富的应用程序,而这些程序运行在能被internet访问到的任何地方。这简直令人难于置信,确实难于置信!

ROBERT HESS:某些迹象告诉我,所有的这些东西给您留下了现象。

JEFFREY RICHTER:是的,有点。

ROBERT HESS:那么,对于观众中跃跃欲试的开发人员,他们想要投身于C#,并要开始编写一些.NET应用程序,在他们跨出第一步之前,需要真正地了解什么?您认为最后还有什么要强调的?

 

JEFFREY RICHTER:我认为,这些开发人员即将面临的一个最大问题就是,他们必须认识到是C#语言揭示了runtime和基类库中的性能,或许假以时日他们会从经验中学到。而许多人将会关注C#,也可能他们会试一试,或关注其它的.NET语言,也有可能会企图做一些不被这些语言所支持的事,接着当然认为这是不可能的。例如:在C#中,所有的数组默认都是基于0的,是以0索引(下标)开始的。但是公共语言运行库支持数组有任何的下边界和上边界。在基类库中构造了一个数组,它具有所设定的上下边界。但是C#自然不提供这些功能。因此,您必须去学习,随着时间的推移,就会了解它是什么,很多时候您或许可以使用其它语言,或者去访问语言的底层系统,语言是位于runtime顶端的,由于某些原因,设计者不让我们去访问底层系统。

ROBERT HESS:似乎就是这样,通过理解runtime底层的所有性能,然后您就可以把这些性能映射(map)给您目前正在使用的任何语言,以便了解它们是否提供给您所需要的功能。例如,我写网页时总是用纯粹的HTML编写,因为我知道它的具体功能是什么。但是假如我必须用FrontPage写,我知道FrontPage有它自己的格式(mindset),关系到网页的显示,并且我知道它能给我提供什么,不能提供什么。偶尔我也不得不转回纯粹的HTML并按这种方式增加某些东西或其它工具,这似乎是同样的事情。

JEFFREY RICHTER:有时在C#中也有这些功能,但却以不同的名字出现,例如,在公式语言库中,虚拟函数被称为family 。于是要在C#中创建一个虚拟函数,就会用protected 限定。对,或不用protected,但是在C#中的protected是等价于公共语言运行库中的family的。噢,搞混了。看看,连我自己也糊涂了。

ROBERT HESS:因此基本的思路听起来好象就是要去理解您正在使用的工具,以及它们在.NET framework底层的运行情况。好了,非常感谢Jeffery,又与您交谈我感到非常荣幸,以后我会找一个时间再次邀请您回来参加这个“show”节目的。

JEFFREY RICHTER:好,我很乐意,谢谢。

ROBERT HESS:这就是程序员Jeffery对C#和.NET framework的看法。他提供给你们一些好资料,以让你们了解更新的开发领域。他讲到了很多的URL地址和源代码例子以及类似的资料。我保证把它们放在本记录稿的后面,所以请继续观看其余的“show”节目,看看还有什么内容。
……(略去与C#无关的谈话)



 

 结束语

 


ROBERT HESS:谢谢您参加另一期的MSDN Show。这一次我们讨论了用C#编程的问题。

 

ERICA WIECHERS:在下一期的MSDN Show节目里,我们将谈论SOAP以及它是如何被整合到.NET编程体系的。

 

ROBERT HESS: 到那时,我们再在网上见面。

 

 

更多资料的链接

 

Microsoft C#资料:

C#综述和介绍(Overview and Introduction to C#,http://msdn.microsoft.com/vstudio/nextgen/technology/csharpintro.asp)

 

C#语言规范(C# Language Specificationhttp://spectre/test/library/default.asp?URL=/library/dotnet/csspec/vclrfcsharpspec_Start.htm

 

MSDN之声:深入C#专栏(MSDN Voices: Deep C# columnhttp://msdn.microsoft.com/voices/deepc.asp

    一个定期的专栏,在这里Bobby Schmidt分享他使用C#的观点和见识。

 

MSDN .NET开发者中心(MSDN Developer Center for .NEThttp://msdn.microsoft.com/net/

     提供更多有关.NET技术的开发资料。

 

C#新闻组(C# Newsgroupnews://msnews.microsoft.com/microsoft.public.dotnet.languages.csharp

与正在学习使用C#的人互相讨论、互相请教。

 

有关Jeffrey Richter谈话的资料:

代码范例(Sample Code:地址不详)

书: Programming Applications for Microsoft Windows

     Programming Server-Side Applications for Windows

(和Jason Clark合写)

Wintellecthttp://www.wintellect.com/,)

Jeffrey 的培训和咨询公司。

TerraServer.NEThttp://terraserver.microsoft.net/

Jeffrey帮助编写的mapping服务。

Jeffrey Richter的主页(http://www.jeffreyrichter.com/)

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

内容简介 · · · · · · 这是一本经典的Windows核心编程指南,从第1版到第5版,引领着数十万程序员走入Windows开发阵营,培养了大批精英。 作为Windows开发人员的必备参考,本书是为打算理解Windows的C和C++程序员精心设计的。第5版全面覆盖Windows XP,Windows Vista和Windows Server 2008中的170个新增函数和Windows特性。书中还讲解了Windows系统如何使用这些特性,我们开发的应用程序又如何充分使用这些特性,如何自行创建新的特性。... 作者简介 · · · · · · Jeffrey Richter是一位在全球享有盛誉的技术作家,尤其在Windows/.NET领域有着杰出的贡献。他的第一本Windows著作Windows 3: A Developer's Guide大获好评,从而声名远扬。后,他又推出了经典著作《Windows 高级编程指南》和《Windows核心编程》。如今这两本书早已成为Windows程序设计领域的颠峰作,培育了几代软件开发设计人员。他的每一本新作问世,我们都有理由相信这是一本巨著,我们想要的一切尽在其中。Jeffery 是Wintellect公司的创始人一,也是MSDN杂志.NET专栏的特邀编辑。现在他正领导开发该公司的.NET程序设计课程,向大众推广.NET技术。因为他自1999年开始就参与了微软.NET框架开发组的咨询工作,与这些一线人员一起经历了.NET的孕育与诞生,所以他对.NET思想的领悟、对.NET的细节熟稔,是其他任何作家难以企及的。他是.NET著作领域中当无愧的一面旗帜。 Christophe Nasarre是Business Objects的软件架构师和开发部门领导,该公司致力于帮助其他企业更好地专注于其主营业务,通过商业智能方案来提升决策能力和业绩。他为Addison-Wesley,APress和Microsoft Press出版的许多图书担任过技术审校,此外还是MSDN Magazine的撰稿人。 目录 · · · · · · 第1部分 必备知识 第1章 错误处理 1.1 定义自己的错误代码 1.2 ErrorShow示例程序 第2章 字符和字符串处理 2.1 字符编码 2.2 ANSI字符和Unicode字符与字符串数据类型 2.3 Windows中的Unicode函数和ANSI函数 2.4 C运行库中的Unicode函数和ANSI函数 2.5 C运行库中的安全字符串函数 2.5.1 初识新的安全字符串函数 2.5.2 在处理字符串时如何获得更多控制 2.5.3 Windows字符串函数 2.6 为何要用Unicode 2.7 推荐的字符和字符串处理方式 2.8 Unicode与ANSI字符串转换 2.8.1 导出ANSI和Unicode DLL函数 2.8.2 判断文本是ANSI还是Unicode 第3章 内核对象 3.1 何为内核对象 3.1.1 使用计数 3.1.2 内核对象的安全性 3.2 进程内核对象句柄表 3.2.1 创建一个内核对象 3.2.2 关闭内核对象 3.3 跨进程边界共享内核对象 3.3.1 使用对象句柄继承 3.3.2 改变句柄的标志 3.3.3 为对象命名 3.3.4 终端服务命名空间 3.3.5 专有命名空间 3.3.5 复制对象句柄 第Ⅱ部分 工作机制 第4章 进程 4.1 编写第一个Windows应用程序 4.1.1 进程实例句柄 4.1.2 进程前一个实例的句柄 4.1.3 进程的命令行 4.1.4 进程的环境变量 4.1.5 进程的关联性 4.1.6 进程的错误模式 4.1.7 进程当前所在的驱动器和目录 4.1.8 进程的当前目录 4.1.9 系统版本 4.2 CreateProcess函数 4.2.1 pszApplicationName和pszCommandLine参数 4.2.2 psaProcess,psaThread和bInheritHandles参数 4.2.3 fdwCreate参数 4.2.4 pvEnvironment参数 4.2.5 pszCurDir参数 4.2.6 psiStartInfo参数 4.2.7 ppiProcInfo参数 4.3 终止进程 4.3.1 主线程的入口点函数返回 4.3.2 ExitProcess函数 4.3.3 TerminateProcess函数 4.3.4 当进程中的所有线程终止时 4.3.5 当进程终止运行时 4.4 子进程 4.5 管理员以标准用户权限运行时 4.5.1 自动提升进程的权限 4.5.2 手动提升进程的权限 4.5.3 何为当前权限上下文 4.5.4 枚举系统中正在运行的
相关推荐
本书针对CLR和.NET Framework 4.5进行深入、全面的探讨,并结合实例介绍了如何利用它们进行设计、开发和调试。全书5部分共29章。第Ⅰ部分介绍CLR基础,第Ⅱ部分解释如何设计类型,第Ⅲ部分介绍基本类型,第Ⅳ部分以核心机制为主题,第Ⅴ部分重点介绍线程处理。 通过本书的阅读,读者可以掌握CLR和.NET Framework的精髓,轻松、高效地创建高性能应用程序。 第I部分 CLR基础 1 第1章 CLR的执行模型 3 1.1 将源代码编译成托管模块 3 1.2 将托管模块合并成程序集 6 1.3 加载公共语言运行时 7 1.4 执行程序集的代码 10 1.4.1 IL和验证 15 1.4.2 不安全的代码 16 1.5 本机代码生成器:NGen.exe 17 1.6 Framework类库 20 1.7 通用类型系统 22 1.8 公共语言规范 24 1.9 与非托管代码的互操作性 28 第2章 生成、打包、部署和管理应用程序及类型 29 2.1 .NET Framework部署目标 29 2.2 将类型生成到模块中 31 2.3 元数据概述 33 2.4 将模块合并成程序集 39 2.4.1 使用Visual Studio IDE将程序集添加到项目中 44 2.4.2 使用程序集链接器 45 2.4.3 为程序集添加资源文件 46 2.5 程序集版本资源信息 47 2.6 语言文化 51 2.7 简单应用程序部署(私有部署的程序集) 52 2.8 简单管理控制(配置) 53 第3章 共享程序集和强命名程序集 57 3.1 两种程序集,两种部署 58 3.2 为程序集分配强名称 59 3.3 全局程序集缓存 63 3.4 在生成的程序集中引用强命名程序集 65 3.5 强命名程序集能防篡改 66 3.6 延迟签名 67 3.7 私有部署强命名程序集 69 3.8 “运行时”如何解析类型引用 70 3.9 高级管理控制(配置) 73 第Ⅱ部分 设计类型 79 第4章 类型基础 81 4.1 所有类型都从System.Object派生 81 4.2 类型转换 83 4.3 命名空间和程序集 86 4.4 运行时的相互关系 90 第5章 基元类型、引用类型和值类型 99 5.1 编程语言的基元类型 99 5.2 引用类型和值类型 106 5.3 值类型的装箱和拆箱 111 5.3.1 使用接口更改已装箱值类型中的字段(以及为什么不应该这样做) 121 5.3.2 对象相等性和同一性 123 5.4 对象哈希码 126 5.5 dynamic基元类型 127 第6章 类型和成员基础 135 6.1 类型的各种成员 135 6.2 类型的可见性 138 6.3 成员的可访问性 139 6.4 静态类 141 6.5 分部类、结构和接口 142 6.6 组件、多态和版本控制 143 6.6.1 CLR如何调用虚方法、属性和事件 145 6.6.2 合理使用类型的可见性和成员的可访问性 148 6.6.3 对类型进行版本控制时的虚方法的处理 150 第7章 常量和字段 155 7.1 常量 155 7.2 字段 156 第8章 方法 161 8.1 实例构造器和类(引用类型) 161 8.2 实例构造器和结构(值类型) 164 8.3 类型构造器 167 8.4 操作符重载方法 170 8.5 转换操作符方法 173 8.6 扩展方法 176 8.6.1 规则和原则 178 8.6.2 用扩展方法扩展各种类型 179 8.6.3 ExtensionAttribute类 181 8.7 分部方法 181 第9章 参数 185 9.1 可选参数和命名参数 185 9.1.1 规则和原则 186 9.1.2 DefaultParameterValueAttribute和OptionalAttribute 188 9.2 隐式类型的局部变量 188 9.3 以传引用的方式向方法传递参数 190 9.4 向方法传递可变数量的参数 195 9.5 参数和返回类型的设计规范 197 9.6 常量性 198 第10章 属性 201 10.1 无参属性 201 10.1.1 自动实现的属性 204 10.1.2 合理定义属性 205 10.1.3 对象和集合初始化器 208 10.1.4 匿名类型 209 10.1.5 System.Tuple类型 212 10.2 有参属性 214 10.3 调用属性访问器方法时的性能 218 10.4 属性访问器的可访问性 219 10.5 泛型属性访问器方法 219 第11章 事件 221 11.1 设计要公开事件的类型 222 11.1.1 第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息 222 11.1.2 第步:定义事件成员 223 11.1.3 第三步:定义负责引发事件的方法来通知事件的登记对象 224 11.1.4 第四步:定义方法将输入转化为期望事件 226 11.2 编译器如何实现事件 226 11.3 设计侦听事件的类型 228 11.4 显式实现事件 230 第12章 泛型 233 12.1 FCL中的泛型 237 12.2 泛型基础结构 238 12.2.1 开放类型和封闭类型 239 12.2.2 泛型类型和继承 240 12.2.3 泛型类型同一性 242 12.2.4 代码爆炸 243 12.3 泛型接口 243 12.4 泛型委托 244 12.5 委托和接口的逆变和协变泛型类型实参 245 12.6 泛型方法 247 12.7 泛型和其他成员 249 12.8 可验证性和约束 250 12.8.1 主要约束 252 12.8.2 次要约束 253 12.8.3 构造器约束 254 12.8.4 其他可验证性问题 254 第13章 接口 259 13.1 类和接口继承 259 13.2 定义接口 260 13.3 继承接口 261 13.4 关于调用接口方法的更多探讨 263 13.5 隐式和显式接口方法实现(幕后发生的事情) 264 13.6 泛型接口 266 13.7 泛型和接口约束 268 13.8 实现多个具有相同方法名和签名的接口 269 13.9 用显式接口方法实现来增强编译时类型安全性 270 13.10 谨慎使用显式接口方法实现 271 13.11 设计:基类还是接口 274 第Ⅲ部分 基本类型 277 第14章 字符、字符串和文本处理 279 14.1 字符 279 14.2 System.String类型 282 14.2.1 构造字符串 282 14.2.2 字符串是不可变的 284 14.2.3 比较字符串 285 14.2.4 字符串留用 290 14.2.5 字符串池 293 14.2.6 检查字符串中的字符和文本元素 293 14.2.7 其他字符串操作 295 14.3 高效率构造字符串 296 14.3.1 构造StringBuilder对象 296 14.3.2 StringBuilder的成员 297 14.4 获取对象的字符串表示:ToString 299 14.4.1 指定具体的格式和语言文化 299 14.4.2 将多个对象格式化成一个字符串 303 14.4.3 提供定制格式化器 304 14.5 解析字符串来获取对象:Parse 306 14.6 编码:字符和字节的相互转换 308 14.6.1 字符和字节流的编码和解码 313 14.6.2 Base-64字符串编码和解码 314 14.7 安全字符串 315 第15章 枚举类型和位标志 319 15.1 枚举类型 319 15.2 位标志 324 15.3 向枚举类型添加方法 328 第16章 数组 329 16.1 初始化数组元素 331 16.2 数组转型 333 16.3 所有数组都隐式派生自System.Array 335 16.4 所有数组都隐式实现IEnumerable,ICollection和IList 336 16.5 数组的传递和返回 337 16.6 创建下限非零的数组 338 16.7 数组的内部工作原理 339 16.8 不安全的数组访问和固定大小的数组 342 第17章 委托 345 17.1 初识委托 345 17.2 用委托回调静态方法 347 17.3 用委托回调实例方法 349 17.4 委托揭秘 349 17.5 用委托回调多个方法(委托链) 353 17.5.1 C#对委托链的支持 356 17.5.2 取得对委托链调用的更多控制 357 17.6 委托定义不要太多(泛型委托) 359 17.7 C#为委托提供的简化语法 360 17.7.1 简化语法1:不需要构造委托对象 360 17.7.2 简化语法2:不需要定义回调方法(lambda表达式) 361 17.7.3 简化语法3:局部变量不需要手动包装到类中即可传给回调方法 364 17.8 委托和反射 367 第18章 定制特性 371 18.1 使用定制特性 371 18.2 定义自己的特性类 374 18.3 特性构造器和字段/属性数据类型 377 18.4 检测定制特性 378 18.5 两个特性实例的相互匹配 382 18.6 检测定制特性时不创建从Attribute派生的对象 384 18.7 条件特性类 387 第19章 可空值类型 389 19.1 C#对可空值类型的支持 391 19.2 C#的空接合操作符 393 19.3 CLR对可空值类型的特殊支持 394 19.3.1 可空值类型的装箱 394 19.3.2 可空值类型的拆箱 395 19.3.3 通过可空值类型调用GetType 395 19.3.4 通过可空值类型调用接口方法 395 第Ⅳ部分 核心机制 397 第20章 异常和状态管理 399 20.1 定义“异常” 399 20.2 异常处理机制 401 20.2.1 try块 402 20.2.2 catch块 402 20.2.3 finally块 404 20.3 System.Exception类 407 20.4 FCL定义的异常类 410 20.5 抛出异常 412 20.6 定义自己的异常类 413 20.7 用可靠性换取开发效率 415 20.8 设计规范和最佳实践 422 20.8.1 善用finally块 423 20.8.2 不要什么都捕捉 424 20.8.3 得体地从异常中恢复 425 20.8.4 发生不可恢复的异常时回滚部分完成的操作——维持状态 426 20.8.5 隐藏实现细节来维系协定 427 20.9 未处理的异常 429 20.10 对异常进行调试 433 20.11 异常处理的性能问题 435 20.12 约束执行区域(CER) 438 20.13 代码协定 441 第21章 托管堆和垃圾回收 447 21.1 托管堆基础 447 21.1.1 从托管堆分配资源 448 21.1.2 垃圾回收算法 449 21.1.3 垃圾回收和调试 451 21.2 代:提升性能 454 21.2.1 垃圾回收触发条件 458 21.2.2 大对象 459 21.2.3 垃圾回收模式 459 21.2.4 强制垃圾回收 462 21.2.5 监视应用程序的内存使用 463 21.3 使用需要特殊清理的类型 464 21.3.1 使用包装了本机资源的类型 470 21.3.2 一个有趣的依赖性问题 474 21.3.3 GC为本机资源提供的其他功能 475 21.3.4 终结的内部工作原理 479 21.3.5 手动监视和控制对象的生存期 481 第22章 CLR寄宿和AppDomain 489 22.1 CLR寄宿 489 22.2 AppDomain 491 跨越AppDomain边界访问对象 494 22.3 卸载AppDomain 504 22.4 监视AppDomain 505 22.5 AppDomain FirstChance异常通知 507 22.6 宿主如何使用AppDomain 507 22.6.1 可执行应用程序 507 22.6.2 Microsoft Silverlight富Internet应用程序 508 22.6.3 Microsoft ASP.NET和XMLWeb服务应用程序 508 22.6.4 Microsoft SQL Server 509 22.6.5 更多的用法只局限于想象力 509 22.7 高级宿主控制 509 22.7.1 使用托管代码管理CLR 509 22.7.2 写健壮的宿主应用程序 510 22.7.3 宿主如何拿回它的线程 511 第23章 程序集加载和反射 515 23.1 程序集加载 516 23.2 使用反射构建动态可扩展应用程序 520 23.3 反射的性能 521 23.3.1 发现程序集中定义的类型 522 23.3.2 类型对象的准确含义 522 23.3.3 构建Exception派生类型的层次结构 524 23.3.4 构造类型的实例 525 23.4 设计支持加载项的应用程序 527 23.5 使用反射发现类型的成员 529 23.5.1 发现类型的成员 530 23.5.2 调用类型的成员 533 23.5.3 使用绑定句柄减少进程的内存消耗 537 第24章 运行时序列化 541 24.1 序列化/反序列化快速入门 542 24.2 使类型可序列化 546 24.3 控制序列化和反序列化 548 24.4 格式化器如何序列化类型实例 551 24.5 控制序列化/反序列化的数据 552 24.6 流上下文 558 24.7 类型序列化为不同类型以及对象反序列化为不同对象 559 24.8 序列化代理 562 24.9 反序列化对象时重写程序集/类型 566 第25章 与WinRT组件互操作 569 25.1 CLR投射与WinRT组件类型系统规则 571 25.2 框架投射 575 25.2.1 从.NET代码中调用异步WinRT API 575 25.2.2 WInRT流和.NET间的互操作 579 25.2.3 在CLR和WinRT间传输数据块 580 25.3 用C#定义WinRT组件 583 第Ⅴ部分 线程处理 589 第26章 线程基础 591 26.1 Windows为什么要支持线程 591 26.2 线程开销 592 26.3 停止疯狂 595 26.4 CPU发展趋势 597 26.5 CLR线程和Windows线程 598 26.6 使用专用线程执行异步的计算限制操作 599 26.7 使用线程的理由 601 26.8 线程调度和优先级 603 26.9 前台线程和后台线程 608 26.10 继续学习 609 第27章 计算限制的异步操作 611 27.1 CLR线程池基础 612 27.2 执行简单的计算限制操作 612 27.3 执行上下文 614 27.4 协作式取消和超时 615 27.5 任务 619 27.5.1 等待任务完成并获取结果 620 27.5.2 取消任务 622 27.5.3 任务完成时自动启动新任务 623 27.5.4 任务可以启动子任务 625 27.5.5 任务内部揭秘 625 27.5.6 任务工厂 627 27.5.7 任务调度器 628 27.6 Parallel的静态For,ForEach和Invoke方法 630 27.7 并行语言集成查询(PLINQ) 634 27.8 执行定时计算限制操作 636 27.9 线程池如何管理线程 639 27.9.1 设置线程池限制 639 27.9.2 如何管理工作者线程 640 第28章 I/O限制的异步操作 643 28.1 Windows如何执行I/O操作 643 28.2 C#的异步函数 647 28.3 编译器如何将异步函数转换成状态机 649 28.4 异步函数扩展性 653 28.5 异步函数和事件处理程序 655 28.6 FCL的异步函数 656 28.7 异步函数和异常处理 658 28.8 异步函数的其他功能 658 28.9 应用程序及其线程处理模型 661 28.10 以异步方式实现服务器 663 28.11 取消I/O操作 664 28.12 有的I/O操作必须同步进行 665 28.13 I/O请求优先级 666 第29章 基元线程同步构造 669 29.1 类库和线程安全 671 29.2 基元用户模式和内核模式构造 672 29.3 用户模式构造 673 29.3.1 易变构造 674 29.3.2 互锁构造 678 29.3.3 实现简单的自旋锁 682 29.3.4 Interlocked Anything模式 685 29.4 内核模式构造 687 29.4.1 Event构造 691 29.4.2 Semaphore构造 693 29.4.3 Mutex构造 694 第30章 混合线程同步构造 697 30.1 一个简单的混合锁 697 30.2 自旋、线程所有权和递归 699 30.3 FCL中的混合构造 701 30.3.1 ManualResetEventSlim类和SemaphoreSlim类 701 30.3.2 Monitor类和同步块 701 30.3.3 ReaderWriterLockSlim类 706 30.3.4 OneManyLock类 709 30.3.5 CountdownEvent类 711 30.3.6 Barrier类 711 30.3.7 线程同步构造小结 712 30.4 著名的双检锁技术 713 30.5 条件变量模式 717 30.6 异步的同步构造 719 30.7 并发集合类 723 译者后记 727
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值