EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.

 

随笔分类 -  C#

摘要:双向信号和竞赛(Two-Way Signaling and Races)Monitor.Pulse方法的一个重要特性是它是异步执行的,这意味着调用pulse方法并不会阻塞自己等待Monitor.Pulse返回。如果任何一个线程在pulsed 对象上等待,它是不会阻塞的,换句话说,调用Monitor.Pulse对程序不会有什么作用,你可以认为Monitor.Pulse方法被忽略了。这样Pulse提供了一个单向通信:一个 pulsing线程悄悄的向一个waiting 线程发送信号。Pulse并不会返回一个值来告诉你waiting线程是否收到信号。但是有时候我们需要知道waiting线程是否受到信号 阅读全文
posted @ 2011-06-02 06:28 LoveJenny 阅读(2754) 评论(5) 推荐(1) 编辑
摘要:上次我们使用AutoResetEvent实现了一个生产/消费者队列。这一次我们要使用Wait和Pulse方法来实现一个更强大的版本,它允许多个消费者,每一个消费者都在自己的线程中运行。我们使用数组来跟踪线程。Thread[] _workers;通过跟踪线程可以让我们在所有的线程都结束后再结束我们的队列任务。每一个消费者线程都执行一个叫做Consume的方法,在一个for循环中,我们可以创建和启动线程。例如: publicPCQueue(intworkerCount){_workers=newThread[workerCount];for(inti=0;i<workerCount;i++) 阅读全文
posted @ 2011-06-01 06:35 LoveJenny 阅读(5451) 评论(3) 推荐(6) 编辑
摘要:Signaling with Wait and Pulse(等待和暂停的信号)早期谈论过等待事件句柄(调用Wait的线程在没有收到另一个线程的通知前会一直阻塞)。Monitor借助它的静态方法Wait,Pulse,PulseAll提供了一个更给力的信号构造,使用这些方法和lock语句,你可以自己实现AutoResetEvent,ManualResetEvent和Semaphore。甚至WaitHandle的WaitAll和WaitAny方法了。怎样使用Wait 和Pulse ?1:定义一个同步对象,例如: Readonly object _locker=new object();2:定义自己的 阅读全文
posted @ 2011-05-31 06:31 LoveJenny 阅读(3871) 评论(1) 推荐(3) 编辑
摘要:在大多数计算机上,增加变量操作不是一个原子操作,需要执行下列步骤: 1. 将实例变量中的值加载到寄存器中。2. 增加或减少该值。3. 在实例变量中存储该值。在多线程环境下,线程会在执行完前两个步骤后被抢先。然后由另一个线程执行所有三个步骤,当第一个线程重新开始执行时,它覆盖实例变量中的值,造成第二个线程执行增减操作的结果丢失。Interlocked可以为多个线程共享的变量提供原子操作。Interlocked.Increment:以原子操作的形式递增指定变量的值并存储结果。Interlocked.Decrement以原子操作的形式递减指定变量的值并存储结果。Interlocked.Add以原子操 阅读全文
posted @ 2011-05-30 06:29 LoveJenny 阅读(5868) 评论(5) 推荐(4) 编辑
摘要:以前我们说过在一些简单的例子中,比如为一个字段赋值或递增该字段,我们需要对线程进行同步,虽然lock可以满足我们的需要,但是一个竞争锁一定会导致阻塞,然后忍受线程上下文切换和调度的开销,在一些高并发和性能比较关键的地方,这些是不能忍受的。.net framework 提供了非阻塞同步构造,为一些简单的操作提高了性能,它甚至都没有阻塞,暂停,和等待线程。Memory Barriers and Volatility (内存栅栏和易失字段 )考虑下下面的代码: int_answer;bool_complete;voidA(){_answer=123;_complete=true;}voidB(){i 阅读全文
posted @ 2011-05-29 08:54 LoveJenny 阅读(9511) 评论(18) 推荐(7) 编辑
摘要:在Framework中存在着4种定时器:其中分为两类,多线程计时器1:System.Threading.Timer2:System.Timers.Timer特殊目的的单线程计时器:1:System.Windows.Forms.Timer(Windows Forms Timer)2:System.Windows.Threading.DispatcherTimer(WPF timer);多线程计时器比较强大,精确,而且可扩展性强;单线程计时器比较安全,对于更新 Windows Forms controls或者WPF这种简单任务来说更方便。System.Threading.Timer是最简单的多线程 阅读全文
posted @ 2011-05-28 09:28 LoveJenny 阅读(16089) 评论(11) 推荐(8) 编辑
摘要:Event-based asynchronous(EAP)在多线程的环境中提供了一个简单的处理方式。它有以下几个特性:支持取消。可以安全的更新WPF或windows Forms 控件。在completion event中可以查询异常信息。“在后台”执行耗时任务(例如下载和数据库操作),但不会中断您的应用程序。同时执行多个操作,每个操作完成时都会接到通知。等待资源变得可用,但不会停止(“挂起”)您的应用程序。使用熟悉的事件和委托模型与挂起的异步操作通信。EAP仅仅只是一个模式而已。,所以这些特性必须都由实现者来实现。在Framework中有少数几个类支持这种模式,最著名的就是Background 阅读全文
posted @ 2011-05-25 22:30 LoveJenny 阅读(4681) 评论(9) 推荐(3) 编辑
摘要:1:CountdownEventFramework 4.0提供了一个CountdownEvent类,主要是让你等待多个线程。考虑下这样的场景:有一个任务,3个人去做,你需要等这3个人都做完了才继续下一步操作。下面就是:classThread15{staticCountdownEvent_countdown=newCountdownEvent(3);publicstaticvoidMainThread(){newThread(SaySomething).Start("I'mthread1");newThread(SaySomething).Start("I& 阅读全文
posted @ 2011-05-24 20:28 LoveJenny 阅读(3347) 评论(2) 推荐(2) 编辑
摘要:1:MutexMutex 就像一个C# lock一样,不同的是它可以跨进程.进入和释放一个Mutex要花费几毫秒,大约比C#的lock慢50倍。使用一个Mutex的实例,调用WaitOne方法来获取锁,ReleaseMutex方法来释放锁。因为Mutex是跨进程的,所以我们可以使用Mutex来检测程序是否已经运行。[代码]2:Semaphore:一个Semaphore就像一个酒吧一样,通过门卫来限... 阅读全文
posted @ 2011-05-24 06:26 LoveJenny 阅读(5933) 评论(17) 推荐(14) 编辑
摘要:1: 考虑下下面的代码:classThreadUnsafe{staticint_val1=1,_val2=1;internalstaticvoidGo(){if(_val2!=0){Console.WriteLine(_val1/_val2);}_val2=0;}}这段代码是非线程安全的,假设有两个线程A,B,A,B都执行到了Go方法的if判断中,假设_val2=1.所以两个线程A,B都通过if判断,A执行了Console.WriteLine方法,然后退出if语句,执行_val2=0,此时_val2=0.但是此时线程B才刚刚执行到Console.WriteLine方法,而此时_val2=0.所 阅读全文
posted @ 2011-05-23 06:27 LoveJenny 阅读(5764) 评论(8) 推荐(4) 编辑
摘要:线程池:每一个线程默认会被分配1MB的内存,在C#中,这些都是实打实的分配的,当一个线程启动的时候,为了分配临时堆栈大约需要花费几百微秒的时间。线程池通过循环利用线程可以让你更高效的利用线程。线程池就像外包的劳务队一样,有任务给他们,他们会管理劳务工的一切,你不需要去花时间去找单个劳务工,然后完成任务就解雇她,对劳务队而言,劳务工完成了你的这个任务,还是会回到自己的团队中的,劳务工的管理也不需要你去负责,因为这由劳务队处理了,如果任务太多了,劳务队会自己招一个劳务工,如果还不够就继续招,但是如果任务比较少,而劳务工又比较多的话,对不起,劳务队的管理人员就会解雇一部分劳务工了。有很多方法可以进入 阅读全文
posted @ 2011-05-22 14:06 LoveJenny 阅读(7124) 评论(5) 推荐(8) 编辑
摘要:1:你可以调用线程的实例方法Join来等待一个线程的结束。例如: publicstaticvoidMainThread(){Threadt=newThread(Go);t.Start();t.Join();Console.WriteLine("Threadthasended!");}staticvoidGo(){for(inti=0;i<1000;i++)Console.Write("y");}在打印了1000个Y之后,后面就会输出”Thread t has ended!”.,你可以在调用Join方法的时候给它一个timeout的参数,例如要超时一 阅读全文
posted @ 2011-05-21 17:11 LoveJenny 阅读(5884) 评论(8) 推荐(13) 编辑
摘要:CLR和操作系统会自动的为应用程序创建一个线程,这个线程叫做主线程(main Thread)如果要创建一个新的线程,可以使用Thread类。下面是一个简单的例子:[代码]for(inti=0;i1000;i++)Console.Write("x");}staticvoidWriteY(){for(inti=0;i1000;i++)Console.Write("y");}}首先创建了一个线程来执... 阅读全文
posted @ 2011-05-21 07:10 LoveJenny 阅读(7675) 评论(19) 推荐(17) 编辑
摘要:跨线程有两种方法。1:this.Dispatcher.BeginInvoke2:SynchronizationContext 在上篇文章中我使用了第一种方法。显然每次都要调用this.Dispatcher.BeginInvoke是一件很“环照”的事情。为了完善RestInvoke,我打算使用SynchronizationContext类,而SynchronizationContext类要和WebRequest关联。为什么要和WebRequest关联呢?因为一个Request对应了一个线程上下文,所以要保存请求时候的线程上下文,然后在成功获取数据后再调用保存的线程上下文来跨线程操作。 首先想到的 阅读全文
posted @ 2011-05-16 19:49 LoveJenny 阅读(2113) 评论(11) 推荐(2) 编辑
摘要:在上篇文章中我们封装了Rest请求,下面我将做一些demo给大家演示RestInvoker怎么使用。首先是服务契约代码:这里注意下CreateByIdAndName方法,因为有两个参数,所以bodyStyle选择wrappedRequest.也就是对Request进行Wrapped的意思。Wrapped的效果就是Json的格式会不一致。View Code [ServiceContract][ServiceKnownType(typeof(Product))]publicinterfaceIRestService{[OperationContract][WebGet(UriTemplate=&q 阅读全文
posted @ 2011-05-15 21:22 LoveJenny 阅读(2241) 评论(2) 推荐(2) 编辑
摘要:我们在上篇文章中讲过WebClient不支持PUT,DELETE.那么WebRequest支持PUT和DELETE吗??于是我们修改PUT代码为:WebRequestwebRequest=WebRequest.Create("http://localhost:19598/ProductService.svc/Product");webRequest.ContentType="application/json";webRequest.Method="PUT";结果还是一样的错误,细心的读者如果反编译过WebClient的话,可以看到内部 阅读全文
posted @ 2011-05-09 20:58 LoveJenny 阅读(4597) 评论(3) 推荐(4) 编辑
摘要:1:新建Silverlight4应用程序,名称为SLClient,选择web承载。2:在MainPage下新建4个按钮,代码如下:<Gridx:Name="LayoutRoot"Background="White"><StackPanel><ButtonContent="GET"x:Name="Get"Click="Get_Click"/><ButtonContent="PUT"x:Name="Put"Click= 阅读全文
posted @ 2011-04-29 23:00 LoveJenny 阅读(3828) 评论(3) 推荐(3) 编辑
摘要:1:新建WCF服务应用程序,名称为RestWCF,选择在新网站中承载.2:新建实体类Product,代码如下:[DataContract]publicclassProduct{[DataMember]publicGuidId{get;set;}[DataMember]publicStringName{get;set;}}3:新建服务契约IProductService:[ServiceContract]publicinterfaceIProductService{[OperationContract][WebGet(UriTemplate="Product")]List< 阅读全文
posted @ 2011-04-27 21:59 LoveJenny 阅读(5077) 评论(13) 推荐(3) 编辑
摘要:两种浮点数据类型--float和double,是为了与ANSI/IEEE Std 754-1985(它是一种用于二进制浮点算术的IEEE标准)相一致而定义的.float值由24位有符号尾数和一个8位有符号指数组成。精度大于为小数点后7位。值的范围是从-3.402823*1038到3.402823*1038 大于0的最小float值是1.401298*10-45这三个值分别对应的是float.Min... 阅读全文
posted @ 2010-06-06 08:14 LoveJenny 阅读(5289) 评论(0) 推荐(1) 编辑
摘要:C#语言支持表B-1所示的11种数值类型,分别为整数,浮点数和小数。在一个c#程序中,整数(没有小数点的数)被认为是一个int类型(除非其值大于最大的int值),根据数据值,该数据依次被视为uint,long,ulong,带小数点的数被认为是一个double值。这就是说(1.0).GetType()==typeof(double).你可以在数字说明上使用前缀来表明自己的意图。其中u代表无符号的意思。因为无符号,所以u代表了数据是正数或0,不可能是负数。A:检查整数溢出考虑下面的代码:short s=32767;s+=1;ushort us=0;us-=1;在第一种情况下,一个有符号的数加1,经 阅读全文
posted @ 2010-06-05 15:41 LoveJenny 阅读(6411) 评论(0) 推荐(0) 编辑

EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.