
任务和并行编程
C#
singhwong
C#,UWP,.Net
展开
-
十八、Lock和await
如果试图在lock块中使用await关键字时使用lock关键字,会得到这个编译错误:cannot await in the body of a lock statement。原因是在await完成之后,该方法可能会在一个不同的线程中运行,而不是await关键字之前的线程(调用线程)。lock关键字需要同一个线程中获取锁和释放锁。下面的代码块会导致编译错误: private static object s_syncLock = new object(); static原创 2020-05-23 16:52:56 · 2134 阅读 · 0 评论 -
ReaderWriterLockSlim类
为了使锁定机制允许锁定多个读取器(而不是一个写入器)访问某个资源,可以使用ReaderWriterLockSlim类。这个类提供了一个锁定功能,如果没有写入器锁定资源,就允许多个读取器访问资源,但只能有一个写入器锁定该资源。ReaderWriterLockSlim类有阻塞或不阻塞的方法来获取读取锁,如阻塞的EnterReadLock()和不阻塞的TryEnterReadLock()方法,还可以使用阻塞的EnterWriteLock()和不阻塞的TryEnterWriteLock()方法获得写入锁定。如果原创 2020-05-23 03:45:23 · 1375 阅读 · 0 评论 -
十六、Barrier类(*)
对于同步,Barrier类非常适用于其中工作有多个任务分支且以后又需要合并工作的情况。Barrier类用于需要同步的参与者。激活一个任务时,就可以动态地添加其他参与者,例如,从父任务中创建子任务。参与者在继续之前,可以等待所有其他参与者完成其工作。BarrierSample有点复杂,但它展示了Barrier类型的功能。下面的应用程序使用一个包含2 000 000个随机字符串的集合。使用多个任务遍历该集合,并统计以a、b、c等开头的字符串个数。工作不仅分布在不同的任务之间,也放在一个任务中。毕竟所有的任务原创 2020-05-22 01:09:01 · 478 阅读 · 0 评论 -
十五、Events类
与互斥和信号量对象一样,事件也是一个系统范围内的资源同步方法。为了从托管代码中使用系统事件,.NET Framework在System.Threading名称空间中提供了ManualResetEvent、AutoResetEvent、ManualResetEventSlim和CountdownEvent类。...原创 2020-05-20 17:05:23 · 439 阅读 · 0 评论 -
十四、Semaphore
信号量非常类似于互斥,其区别是,信号量可以同时由多个线程使用。信号量是一种计数的互斥锁定。使用信号量,可以定义允许同时访问受其锁定保护的资源的线程个数。如果需要限制可以访问可用资源的线程数,信号量就很有用。例如,如果系统有3个物理端口可用,就允许3个线程同时访问I/O端口,但第4个线程需要等待前3个线程中的一个释放资源。.NET Core为信号量功能提供了两个类Semaphore和SemaphoreSlim。Semaphore类可以命名,使用系统范围内的资源,允许在不同进程之间同步。SemaphoreS原创 2020-05-19 18:46:50 · 175 阅读 · 0 评论 -
十三、Mutex类
Mutex(mutual exclusion,互斥)是.NET Framework中提供跨多个进程同步访问的一个类。它非常类似于Monitor类,因为它们都只有一个线程拥有锁定。只有一个线程能获得互斥锁定,访问受互斥保护的同步代码区域。在Mutex类的构造函数中,可以指定互斥是否最初应由主调线程拥有,定义互斥的名称,获得互斥是否已存在的信息。在下面的示例代码中,第3个参数定义为输出参数,接收一个表示互斥是否为新建的布尔值。如果返回的值是false,就表示互斥已经定义。互斥可以在另一个进程中定义,因为操作原创 2020-05-19 17:52:07 · 518 阅读 · 0 评论 -
十二、WaitHandle基类
WaitHandle是一个抽象基类,用于等待一个信号的设置。可以等待不同的信号,因为WaitHandle是一个基类,可以从中派生一些类。使用WaitHandle基类可以等待一个信号的出现(WaitOne()方法)、等待必须发出信号的多个对象(WaitAll()方法),或者等待多个对象中的一个(WaitAny()方法)。WaitAll()和WaitAny()是WaitHandle类的静态方法,接收一个WaitHandle参数数组。WaitHandle基类有一个SafeWaitHandle属性,其中可以原创 2020-05-19 02:23:23 · 319 阅读 · 0 评论 -
十一、SpinLock结构
如果基于对象的锁定对象(Monitor)的系统开销由于垃圾收集而过高,就可以使用SpinLock结构。如果有大量的锁定(例如,列表中的每个节点都有一个锁定),且锁定的时间总是非常短,SpinLock结构就很有用。应避免使用多个SpinLock结构,也不要调用任何可能阻塞的内容。除了体系结构上的区别之外,SpinLock结构的用法非常类似于Monitor类。使用Enter()或TryEnter()方法获得锁定,使用Exit()方法释放锁定。SpinLock结构还提供了属性IsHeld和IsHeldByCu原创 2020-05-19 02:14:17 · 142 阅读 · 0 评论 -
十、Monitor类
lock语句由C#编译器解析为使用Monitor类,下面的lock语句: lock (obj) { // synchronized region for obj }被解析为调用Enter()方法,该方法会一直等待,直到线程锁定对象为止。一次只有一个线程能锁定对象。只要解除了锁定,线程就可以进入同步阶段。Monitor类的Exit()方法解除了锁定。编译器把Exit()方法放在try块的finall原创 2020-05-19 01:36:02 · 261 阅读 · 0 评论 -
九、Interlocked类
Interlocked类用于使变量的简单语句原子化。i++不是线程安全的,它的操作包括从内存中获取一个值,给该值递增1,再将它存储会内存。这些操作都可能会被线程调度器打断。Interlocked类提供了以线程安全的方式递增、递减、交换和读取值的方法。...原创 2020-05-18 19:53:52 · 310 阅读 · 0 评论 -
八、lock语句和线程安全
C#为多个线程的同步提供了自己的关键字:lock语句。lock语句是设置锁定和解除锁定的一种简单方式。在添加lock语句之前,先进入另一个争用条件。SharedState类说明了如何使用线程之间的共享状态,并共享一个整数值。 class SharedState { public int State { get; set; } }下面所有同步示例的代码(SingletonWPF除外)都使用如下名称空间:SystemSystem.Collections.G原创 2020-05-16 19:09:49 · 339 阅读 · 0 评论 -
7. 线程问题
用多个线程编程并不容易。在启动访问相同数据的多个线程时,会间歇性地遇到难以发现的问题。如果使用任务、并行LINQ或Parallel类,也会遇到这些问题。为了避免这些问题,必须特别注意同步问题和多个线程可能发生的其他问题。下面探讨与线程相关的问题:争用条件和死锁。ThreadingIssues示例的代码使用了如下名称空间:System.DiagnosticsSystem.ThreadingSystem.Threading.Tasksstatic System.Console可以使用命令原创 2020-05-16 01:40:25 · 193 阅读 · 0 评论 -
六、Timer类
使用计时器,可以重复调用方法。原创 2020-05-15 22:14:26 · 341 阅读 · 0 评论 -
五、数据流
Parallel类、Task类和Parallel LINQ为数据并行性提供了很多帮助。但是,这些类不能直接支持数据流的处理,以及并行转换数据。此时,需要使用Task Parallel Library Data Flow(TPL Data Flow)。数据流示例的代码使用了如下名称空间:SystemSystem.IOSystem.ThreadingSystem.Threading.TasksSystem.Threading.Tasks.DataFlow1.使用动作块...原创 2020-05-15 03:21:24 · 454 阅读 · 0 评论 -
四、取消架构
.NET包含一个取消架构,允许以标准方式取消长时间运行的任务。每个阻塞调用都应该支持这种机制。当然目前并不是所有阻塞调用都实现了这个新技术,但越来越多的阻塞调用都支持它。已经提供了这种机制的技术有任务、并发集合类、并行LINQ和几种同步机制。取消架构基于协作行为,它不是强制的。长时间运行的任务会检查它是否被取消,并相应地返回控制权。支持取消的方法接受一个CancellationToken参数。这个类定义了IsCancellationRequested属性,其中长时间运行的操作可以检查它是否应终止。长原创 2020-05-14 00:59:19 · 267 阅读 · 0 评论 -
三、任务
为了更好地控制并行操作,可以使用System.Threading.Tasks名称空间中的Task类。原创 2020-05-10 15:02:41 · 226 阅读 · 0 评论 -
二、Parallel类
Parallel类是对线程的一个很好的抽象。该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性。Parallel类定义了并行的for和foreach的静态方法。对于C#的for和foreach语句而言,循环从一个线程中运行。Parallel类使用多个任务,因此使用多个线程来完成这个作业。Parallel.For()和Parallel.ForEach()方法在每次迭代中调用相同的代码,而Parallel.Invoke()方法允许同时调用不同的方法。Parallel.原创 2020-05-08 18:24:48 · 808 阅读 · 0 评论 -
一、概述(任务和并行编程)
使用多线程有几个原因。原创 2020-05-08 00:10:27 · 247 阅读 · 0 评论