.NET

Understanding C# async / await 第2章

Understanding C# async / await Understanding C# async / await 第1章原文地址 Understanding C# async / await 第2章原文地址 Understanding C# async / await 第3章原文地址 2 The Awaitable-Awaiter Pattern 2.1 What is awaitable 第1部分显示了所有Task类都是awaitable的。实际上,还有其他awaitable类型。如下所示: Task<int> task = new Task<int>(() => 0); int result = await task.ConfigureAwait(false); // Returns a ConfiguredTaskAwaitable<TResult>. The returned ConfiguredTaskAwaitable<TResult> struct is awaitable. And it is not Task at all: public struct ConfiguredTaskAwaitable<TResult> { private readonly ConfiguredTaskAwaiter m_configuredTaskAwaiter; internal ConfiguredTaskAwaitable(Task<TResult> task, bool continueOnCapturedContext) { this.

C#中的Attribute学习笔记

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com C#的Attribute的一些细节描述: 1 C#的attribute,通常翻译为“ 特性 ”。经常出现的英文单词则翻译为“ 属性 ” 2 C#的attribute可以视为是一种 附着物。就像牡蛎吸附在船底或礁石上一样。这些附着物的作用是为它们的附着体,追加上一些额外的信息。而这些信息保存在附着物的体内。对,也即是被编译器编译进 程序集(assembly) 的 元数据(Metadata) 里,在程序运行的时候,随时可以从元数据里提取出这些附加信息,来决策或影响程序的运行。 3 C#的attribute不是什么别的,其本质上就是一个类,而且这个类在使用上要遵循以下的一些规则: 3.1 不使用new操作符来产生实例,而是使用在方括号里调用构造函数的来产生实例。构造函数的参数是一定要写的,有几个就得写几个。且参数的顺序不能错 3.2 方括号必需紧挨着放置在被附着目标的前面。 3.3 因为方括号里空间有限,不能像使用new那样先构造对象后,再对对象的 属性(Property) 一一赋值。因此,对Attribute实例属性的赋值,也需写在构造函数的圆括号里。但对property的赋值,可有可无,这是因为编译器肯定对property设置一个默认值。对多个property的赋值先后顺序也没有关系。 能被Attribute所附着的目标种类 Attribute能附着的目标的种类在枚举类型AttributeTargets中有定义,代码如下: namespace System { [ComVisible(true)] [Flags] public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, Enum = 16, Constructor = 32, Method = 64, Property = 128, Field = 256, Event = 512, Interface = 1024, Parameter = 2048, Delegate = 4096, ReturnValue = 8192, GenericParameter = 16384, All = 32767 } } 从上面的定义可以看到,如果有指定多个attribute所能附着的目标类型的话,在设置AttributeTragets类型值是用按位或操作符连起来就好,例如:AttributeTargets.

C#中的迭代器和yield

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 在.NET中通过使用接口IEnumerator和IEnumerable及其泛型等价物。来封装 迭代器模式 。所谓 迭代器模式 即是:允许你访问一个数据项序列,能依次遍历该序列中的每一项元素,而无需关心元素在序列内部的组织形式。 1.非泛型版本的IEnumerator和IEnumerable接口 首先看IEnumerator接口的定义,代码如下: public interface IEnumerator { /* 获取集合中位于枚举数当前位置的元素。在下列任一情况下,不定义Current: 1 枚举器位于集合中第一个元素之前,紧跟在创建枚举器之后。 在读取Current的值之前, 必须调用MoveNext,以将枚举器前进到集合的第一个元素。 2 对MoveNext的最后一次调用返回了 false,指示集合的末尾。 3 由于对集合所做的更改(如添加、修改或删除元素),枚举器无效。 在调用 Current 之前,MoveNext返回相同的对象。 MoveNext将Current设置为下一个元素。 */ object Current { get; } /* 将枚举数推进到集合的下一个元素。 如果枚举数已成功地推进到下一个元素,则为true; 如果枚举数传递到集合的末尾,则为false。 在创建枚举器之后,或在调用Reset方法之后,枚举数将定位到集合的第一个元素之前, 对MoveNext方法的第一次调用将枚举器移动到集合的第一个元素上。 如果MoveNext越过集合的末尾,则枚举器将定位到集合中的最后一个元素之后,MoveNext返回false。 当枚举器位于此位置时,对MoveNext的后续调用也将返回false,直到调用Reset。 如果对集合所做的更改(如添加、修改或删除元素),则MoveNext的行为是不确定的。 */ bool MoveNext(); /* 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。 */ void Reset(); } 顾名思义,IEnumerator就是表征一个“ 迭代器 ”(又可称为 枚举器 )应有的功能接口,该接口所函数的方法如上述代码注释中所描述,接下来看IEumerable接口,代码如下: public interface IEnumerable { IEnumerator GetEnumerator(); } IEnumerable用来表征“一个数据集合是 可迭代 的( 可枚举 的)”,即是说该数据集合中的每个元素都是可以被一一迭代的。IEnumerable接口也很简单,只有一个方法,就是返回 能访问到该数据集合每个元素的迭代器 。

.NET Framework的IAsyncResult接口的细节

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 概述 IAsynResult接口用来表征一个异步操作的结果。它的定义声明如下: [System.Runtime.InteropServices.ComVisible(true)] public interface IAsyncResult { object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { get; } bool IsCompleted { get; } } 有一些.NET Framework预定义的类是继承实现这个接口,如下: AsyncResult SecurityTokenProvider.SecurityTokenAsyncResult AsyncResult Task CommittableTransaction 示例程序 接下来的示例演示了如何使用了IAsyncResult接口中的AsyncWaitHandle属性,去获取到一个WaitHandle类型的值,以及如何使用一个delegate去等待一个异步调用。当异步调用完成后,WaitHandle类型的返回值将会被赋值上。这示例由两个类组成,一个是包含了异步调用函数的类;另一个类则是包含了调用异步函数的方法。 using System; using System.Threading; namespace Examples.AdvancedProgramming.AsynchronousOperations { public class AsyncDemo { // 将要被异步执行的函数 public string TestMethod(int callDuration, out int threadId) { Console.WriteLine("Test method begins."); Thread.Sleep(callDuration); // 被异步执行的函数所在的线程休眠callDuration所指定的时间 threadId = Thread.CurrentThread.ManagedThreadId; // 拿到系统给本异步执行的函数分配的运行线程的id return String.

NET Framework中的Socket类的BeginReceive和EndReceive成员方法详解

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 分类 信息 类所属的空间: System.Net.Sockets 类所属于的程序集: System.dll, netstandard.dll, System.Net.Sockets.dll, System.Net.dll 使用BeginReceive和EndReceive的示例代码 using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; // State object for receiving data from remote device. public class StateObject { public Socket workSocket = null; // Socket连接的对象 public const int BufferSize = 256; // 客户端接受socket数据的缓冲区字节数大小 public byte[] buffer = new byte[BufferSize]; // 客户端接受socket数据的缓冲区 public StringBuilder sb = new StringBuilder();// 客户端接受数据字符串的容器 } public class AsynchronousClient { private const int port = 11000; // 端口号 // ManualResetEvent类详见 http://www.