目录

目录

 

  • 层层大纲
  • 一、前言
  • 二 、目录结构
  • 肆 、章节结构
  • 五 、相关链接
  • 1.1
    简介
  • 1.2
    成立职责
  • 1.3
    使用职分履行基本的操作
  • 1.4
    组合职分
  • 1.5
    将APM情势转换为职分
  • 1.6
    将EAP格局转换为职务
  • 1.7
    完成撤消选项
  • 1.8
    处理职务中的非常
  • 1.9
    相互运行职责
  • 1.10
    使用TaskScheduler配置任务履行
  • 参考书籍
  • 作者水平有限,假如不当欢迎各位批评指正!

Atitit.并发编程原理与概论 attilax总括

 



 

Atitit.并发编制程序原理与概论 attilax计算


本体系首页链接:[C#二十四线程编制程序类别(一)-
简介 ]

 

 

不可胜计大纲

近日只整理到第①章,线程同步,作者前面会日益更新,争取能把那本书中精华的知识都享受出来。
C#四线程编制程序类别(一)-
简介
C#三十二线程编制程序类别(二)-
线程基础
C#三十二线程编制程序连串(三)-
线程同步
C#二十八线程编制程序连串(四)-
使用线程池
C#二十多线程编制程序类别(五)-
使用任务并行库

源码下载点击链接
示范源码下载


1.
面世一般涉及如下多少个方面:2

 

一、前言

在C#上学进度中,四线程平素都是相比较难的一些,因为个中涉及到许多与操作系统相关的学问。比如:怎么着进展十二线程编程、线程同步、线程锁、线程异步、并行编制程序、并行集合等等的文化。所以作者在念书进程中也是遇上了重重困难,而且直接没有好的科目。

而是作者在浏览GitHub时,发现有大佬已经引进了一本新书,《MULTITHREADING
WITH C# COOKBOOK SECOND
EDITION》
,个中第贰就是讲怎么在C#中接纳八线程的。看到那本书小编是如获珍宝,终于能有时机系统的学习十六线程相关的学问了。

于是便有了那四个开篇,那一个越多的是阅读那本书的笔记和某个如约书本上写的范例程序,当然也会有一部分谈得来的盘算。

1.1 简介

在前头的多少个章节中,就线程的运用和十六线程相关的始末展开了介绍。因为线程涉及到异步、同步、分外传递等难点,所以在档次中选用十二线程的代价是比较高昂的,要求编写制定大量的代码来实现科学和健壮性。

为了化解那样局地的标题,在.Net Framework 4.0中引入了贰个有关一步操作的API。它称为职责并行库(Task
Parallel
Library)
。然后在.Net Framwork 4.5中对它实行了一线的创新,本文的案例都以用风尚版本的TPL库,而且大家仍是能够使用C#
5.0的新特点await/async来简化TAP编制程序,当然那是后来才介绍的。

TPL内部使用了线程池,不过效用更高。在把线程归还回线程池此前,它会在同一线程中逐一执行稍微Task,那样防止了有的小职分上下文切换浪费时间片的难点。

职分是指标,个中封装了以异步格局实行的劳作,可是委托也是包装了代码的靶子。任务和嘱托的分别在于,委托是同步的,而任务是异步的。

在本章中,大家将会谈谈什么利用TPL库来进展职责之间的结缘同步,怎样将残留的APM和EAP格局转换为TPL形式等等。

2.
线程安全性 ( 2.2 原子性    2.3 加锁机制2

1.
出现一般涉及如下几个方面:2

二 、目录结构

本书一共分成十五个章节,分别从线程基础、线程同步、线程池、Task并行库、C#
6.0风味、并发集合类、PLINQ、反应式编制程序、异步I/O、并行变成形式和在UWP
.Net Core中利用来实现的介绍了C#二十三十六线程编制程序。如下图所示。

金沙注册送58 1

屈居百度脑图链接

笔者认为本书确实是一本数一数二的好书,回顾起那段被四线程虐过的小日子。粗略的过了壹回以后就打算立时拿出去分享给大家,后文有连带的选购链接,大家也得以向来在某宝、某东搜索关键字,价格也是比较便宜的,多多扶助正版。

1.2 创立任务

在本节中,首若是出现说法了什么创立1个任务。其关键运用了System.Threading.Tasks取名空间下的Task类。该类能够被实例化并且提供了一组静态方法,能够方便神速的创始任务。

在上边实例代码中,分别延时了三种常见的天职创建格局,并且创设任务是能够钦赐职分创建的选项,从而实现最优的创设方式。

TaskCreationOptions中累计有八个枚举,枚举是可以动用|运算符组合定义的。其枚举如下表所示。

成员名称 说明
AttachedToParent 指定将任务附加到任务层次结构中的某个父级。 默认情况下,子任务(即由外部任务创建的内部任务)将独立于其父任务执行。 可以使用 TaskContinuationOptions.AttachedToParent 选项以便将父任务和子任务同步。请注意,如果使用 DenyChildAttach 选项配置父任务,则子任务中的 AttachedToParent 选项不起作用,并且子任务将作为分离的子任务执行。有关详细信息,请参阅附加和分离的子任务
DenyChildAttach 指定任何尝试作为附加的子任务执行(即,使用 AttachedToParent 选项创建)的子任务都无法附加到父任务,会改成作为分离的子任务执行。 有关详细信息,请参阅附加和分离的子任务
HideScheduler 防止环境计划程序被视为已创建任务的当前计划程序。 这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 Default 当前计划程序。
LongRunning 指定任务将是长时间运行的、粗粒度的操作,涉及比细化的系统更少、更大的组件。 它会向 TaskScheduler 提示,过度订阅可能是合理的。 可以通过过度订阅创建比可用硬件线程数更多的线程。 它还将提示任务计划程序:该任务需要附加线程,以使任务不阻塞本地线程池队列中其他线程或工作项的向前推动。
None 指定应使用默认行为。
PreferFairness 提示 TaskScheduler 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
RunContinuationsAsynchronously 强制异步执行添加到当前任务的延续任务。请注意,RunContinuationsAsynchronously 成员在以 .NET Framework 4.6 开头的 TaskCreationOptions 枚举中可用。
static void Main(string[] args)
{
    // 使用构造方法创建任务
    var t1 = new Task(() => TaskMethod("Task 1"));
    var t2 = new Task(() => TaskMethod("Task 2"));

    // 需要手动启动
    t2.Start();
    t1.Start();

    // 使用Task.Run 方法启动任务  不需要手动启动
    Task.Run(() => TaskMethod("Task 3"));

    // 使用 Task.Factory.StartNew方法 启动任务 实际上就是Task.Run
    Task.Factory.StartNew(() => TaskMethod("Task 4"));

    // 在StartNew的基础上 添加 TaskCreationOptions.LongRunning 告诉 Factory该任务需要长时间运行
    // 那么它就会可能会创建一个 非线程池线程来执行任务  
    Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

    ReadLine();
}

static void TaskMethod(string name)
{
    WriteLine($"任务 {name} 运行,线程 id {CurrentThread.ManagedThreadId}. 是否为线程池线程: {CurrentThread.IsThreadPoolThread}.");
}

运转结果如下图所示。

金沙注册送58 2

2.1.
线程封闭3.3.1Ad-hoc线程封闭   3.3.2 栈封闭   3.3.3ThreadLocal类2

2.
线程安全性 ( 2.2 原子性    2.3 加锁机制2

④ 、章节结构

本书主倘诺偏实践应用有的,在那之中每一个章节中的技术验证都分为多少个部分,准备干活(Getting
ready)、达成情势(How to do it…)和落到实处原理(How it works…)

正文节节选第②章的率先小节举例,首先是准备工作。

1.准备工作

金沙注册送58 3

2.完结格局

金沙注册送58 4金沙注册送58 5

3.兑现原理

金沙注册送58 6

海外的书一般都以比较偏理论,像那种理论和推行结合的依旧比较少,所以第权且间推荐给我们。

1.3 使用职分执行基本的操作

在本节中,使用任务履行基本的操作,并且获得职责执行到位后的结果值。本节内容相比较简单,在此不做过多介绍。

以身作则代码如下,在主线程中要获得结果值,常用的点子就是造访task.Result质量,假如职务线程还没执行完结,那么会阻塞主线程,直到线程执行完。若是职责线程执行完结,那么将直接获得运算的结果值。

Task 3中,使用了task.Status来打印线程的气象,线程每一种情状的有血有肉意思,将在下一节中介绍。

static void Main(string[] args)
{
    // 直接执行方法 作为参照
    TaskMethod("主线程任务");

    // 访问 Result属性 达到运行结果
    Task<int> task = CreateTask("Task 1");
    task.Start();
    int result = task.Result;
    WriteLine($"运算结果: {result}");

    // 使用当前线程,同步执行任务
    task = CreateTask("Task 2");
    task.RunSynchronously();
    result = task.Result;
    WriteLine($"运算结果:{result}");

    // 通过循环等待 获取运行结果
    task = CreateTask("Task 3");
    WriteLine(task.Status);
    task.Start();

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }

    WriteLine(task.Status);
    result = task.Result;
    WriteLine($"运算结果:{result}");

    Console.ReadLine();
}

static Task<int> CreateTask(string name)
{
    return new Task<int>(() => TaskMethod(name));
}

static int TaskMethod(string name)
{
    WriteLine($"{name} 运行在线程 {CurrentThread.ManagedThreadId}上. 是否为线程池线程 {CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(2));

    return 42;
}

运转结果如下,可知Task 1
Task 2均是运作在主线程上,并非线程池线程。

金沙注册送58 7

3.
异步2

2.1.
线程封闭3.3.1Ad-hoc线程封闭   3.3.2 栈封闭   3.3.3ThreadLocal类2

伍 、相关链接

沾满购买地点,大家依旧多多支撑正版.

《MULTITHREADING WITH C# COOKBOOK SECOND
EDITION》选购地方

补充,本书有普通话翻译版本,由黄博文大佬翻译,不过好像依旧第③版。

《C#四线程编制程序实战》购买位置

1.4 组合职责

在本节中,突显了职务之中一个有力的功能,这正是组成职分。通过整合职务可很好的描述职分与任务之间的异步、同步关系,大大降低了编制程序的难度。

组成任务首若是通过task.ContinueWith()task.WhenAny()task.WhenAll()等和task.GetAwaiter().OnCompleted()办法来兑现。

在使用task.ContinueWith()措施时,须求注意它也可传递一文山会海的枚举选项TaskContinuationOptions,该枚举选项和TaskCreationOptions类似,其实际定义如下表所示。

成员名称 说明
AttachedToParent 如果延续为子任务,则指定将延续附加到任务层次结构中的父级。 只有当延续前面的任务也是子任务时,延续才可以是子任务。 默认情况下,子任务(即由外部任务创建的内部任务)将独立于其父任务执行。 可以使用 TaskContinuationOptions.AttachedToParent 选项以便将父任务和子任务同步。请注意,如果使用 DenyChildAttach 选项配置父任务,则子任务中的 AttachedToParent 选项不起作用,并且子任务将作为分离的子任务执行。有关更多信息,请参见Attached and Detached Child Tasks
DenyChildAttach 指定任何使用 TaskCreationOptions.AttachedToParent 选项创建,并尝试作为附加的子任务执行的子任务(即,由此延续创建的任何嵌套内部任务)都无法附加到父任务,会改成作为分离的子任务执行。 有关详细信息,请参阅附加和分离的子任务
ExecuteSynchronously 指定应同步执行延续任务。 指定此选项后,延续任务在导致前面的任务转换为其最终状态的相同线程上运行。如果在创建延续任务时已经完成前面的任务,则延续任务将在创建此延续任务的线程上运行。 如果前面任务的 CancellationTokenSource 已在一个 finally(在 Visual Basic 中为 Finally)块中释放,则使用此选项的延续任务将在该 finally 块中运行。 只应同步执行运行时间非常短的延续任务。由于任务以同步方式执行,因此无需调用诸如 Task.Wait 的方法来确保调用线程等待任务完成。
HideScheduler 指定由延续通过调用方法(如 Task.RunTask.ContinueWith)创建的任务将默认计划程序 (TaskScheduler.Default) 视为当前的计划程序,而不是正在运行该延续的计划程序。
LazyCancellation 在延续取消的情况下,防止延续的完成直到完成先前的任务。
LongRunning 指定延续将是长期运行的、粗粒度的操作。 它会向 TaskScheduler 提示,过度订阅可能是合理的。
None 如果未指定延续选项,应在执行延续任务时使用指定的默认行为。 延续任务在前面的任务完成后以异步方式运行,与前面任务最终的 Task.Status 属性值无关。 如果延续为子任务,则会将其创建为分离的嵌套任务。
NotOnCanceled 指定不应在延续任务前面的任务已取消的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Canceled,则前面的任务会取消。 此选项对多任务延续无效。
NotOnFaulted 指定不应在延续任务前面的任务引发了未处理异常的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Faulted,则前面的任务会引发未处理的异常。 此选项对多任务延续无效。
NotOnRanToCompletion 指定不应在延续任务前面的任务已完成运行的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.RanToCompletion,则前面的任务会运行直至完成。 此选项对多任务延续无效。
OnlyOnCanceled 指定只应在延续前面的任务已取消的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Canceled,则前面的任务会取消。 此选项对多任务延续无效。
OnlyOnFaulted 指定只有在延续任务前面的任务引发了未处理异常的情况下才应安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Faulted,则前面的任务会引发未处理的异常。OnlyOnFaulted 选项可保证前面任务中的 Task.Exception 属性不是 null。 你可以使用该属性来捕获异常,并确定导致任务出错的异常。 如果你不访问 Exception 属性,则不会处理异常。 此外,如果尝试访问已取消或出错的任务的 Result 属性,则会引发一个新异常。此选项对多任务延续无效。
OnlyOnRanToCompletion 指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.RanToCompletion,则前面的任务会运行直至完成。 此选项对多任务延续无效。
PreferFairness 提示 TaskScheduler 按任务计划的顺序安排任务,因此较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
RunContinuationsAsynchronously 指定应异步运行延续任务。 此选项优先于 TaskContinuationOptions.ExecuteSynchronously。

以身作则代码如下所示,使用ContinueWith()OnCompleted()方法结合了职责来运营,搭配不一致的TaskCreationOptionsTaskContinuationOptions【金沙注册送58】二十十六线程编程体系,并发编制程序原理与概论。来完成不一致的功力。

static void Main(string[] args)
{
    WriteLine($"主线程 线程 Id {CurrentThread.ManagedThreadId}");

    // 创建两个任务
    var firstTask = new Task<int>(() => TaskMethod("Frist Task",3));
    var secondTask = new Task<int>(()=> TaskMethod("Second Task",2));

    // 在默认的情况下 ContiueWith会在前面任务运行后再运行
    firstTask.ContinueWith(t => WriteLine($"第一次运行答案是 {t.Result}. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程: {CurrentThread.IsThreadPoolThread}"));

    // 启动任务
    firstTask.Start();
    secondTask.Start();

    Sleep(TimeSpan.FromSeconds(4));

    // 这里会紧接着 Second Task运行后运行, 但是由于添加了 OnlyOnRanToCompletion 和 ExecuteSynchronously 所以会由运行SecondTask的线程来 运行这个任务
    Task continuation = secondTask.ContinueWith(t => WriteLine($"第二次运行的答案是 {t.Result}. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}"),TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);

    // OnCompleted 是一个事件  当contiuation运行完成后 执行OnCompleted Action事件
    continuation.GetAwaiter().OnCompleted(() => WriteLine($"后继任务完成. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程 {CurrentThread.IsThreadPoolThread}"));

    Sleep(TimeSpan.FromSeconds(2));
    WriteLine();

    firstTask = new Task<int>(() => 
    {
        // 使用了TaskCreationOptions.AttachedToParent 将这个Task和父Task关联, 当这个Task没有结束时  父Task 状态为 WaitingForChildrenToComplete
        var innerTask = Task.Factory.StartNew(() => TaskMethod("Second Task",5), TaskCreationOptions.AttachedToParent);

        innerTask.ContinueWith(t => TaskMethod("Thrid Task", 2), TaskContinuationOptions.AttachedToParent);

        return TaskMethod("First Task",2);
    });

    firstTask.Start();

    // 检查firstTask线程状态  根据上面的分析 首先是  Running -> WatingForChildrenToComplete -> RanToCompletion
    while (! firstTask.IsCompleted)
    {
        WriteLine(firstTask.Status);

        Sleep(TimeSpan.FromSeconds(0.5));
    }

    WriteLine(firstTask.Status);

    Console.ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务 {name} 正在运行,线程池线程 Id {CurrentThread.ManagedThreadId},是否为线程池线程: {CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));

    return 42 * seconds;
}

运作结果如下图所示,与预期结果同样。个中使用了task.Status来打字与印刷职务运转的气象,对于task.Status的图景具体意思如下表所示。

成员名称 说明
Canceled 该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的 CancellationToken 发出了信号。 有关详细信息,请参阅任务取消
Created 该任务已初始化,但尚未被计划。
Faulted 由于未处理异常的原因而完成的任务。
RanToCompletion 已成功完成执行的任务。
Running 该任务正在运行,但尚未完成。
WaitingForActivation 该任务正在等待 .NET Framework 基础结构在内部将其激活并进行计划。
WaitingForChildrenToComplete 该任务已完成执行,正在隐式等待附加的子任务完成。
WaitingToRun 该任务已被计划执行,但尚未开始执行。

金沙注册送58 8

4.
共同与锁关键字2

3.
异步2

1.5 将APM情势转换为天职

在眼下的章节中,介绍了遵照IAsyncResult接口完结了BeginXXXX/EndXXXX措施的就叫APM格局。APM方式尤其古老,那么什么样将它转换为TAP形式吧?对于普遍的二种APM形式异步义务,大家一般选用选择Task.Factory.FromAsync()方法来贯彻将APM模式转换为TAP模式

演示代码如下所示,相比简单不作过多介绍。

static void Main(string[] args)
{
    int threadId;
    AsynchronousTask d = Test;
    IncompatibleAsychronousTask e = Test;

    // 使用 Task.Factory.FromAsync方法 转换为Task
    WriteLine("Option 1");
    Task<string> task = Task<string>.Factory.FromAsync(d.BeginInvoke("异步任务线程", CallBack, "委托异步调用"), d.EndInvoke);

    task.ContinueWith(t => WriteLine($"回调函数执行完毕,现在运行续接函数!结果:{t.Result}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);
    Sleep(TimeSpan.FromSeconds(1));

    WriteLine("----------------------------------------------");
    WriteLine();

    // 使用 Task.Factory.FromAsync重载方法 转换为Task
    WriteLine("Option 2");

    task = Task<string>.Factory.FromAsync(d.BeginInvoke,d.EndInvoke,"异步任务线程","委托异步调用");

    task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);
    Sleep(TimeSpan.FromSeconds(1));

    WriteLine("----------------------------------------------");
    WriteLine();

    // 同样可以使用 FromAsync方法 将 BeginInvoke 转换为 IAsyncResult 最后转换为 Task
    WriteLine("Option 3");

    IAsyncResult ar = e.BeginInvoke(out threadId, CallBack, "委托异步调用");
    task = Task<string>.Factory.FromAsync(ar, _ => e.EndInvoke(out threadId, ar));

    task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result},线程Id {threadId}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);

    ReadLine();
}

delegate string AsynchronousTask(string threadName);
delegate string IncompatibleAsychronousTask(out int threadId);

static void CallBack(IAsyncResult ar)
{
    WriteLine("开始运行回调函数...");
    WriteLine($"传递给回调函数的状态{ar.AsyncState}");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    WriteLine($"线程池工作线程Id:{CurrentThread.ManagedThreadId}");
}

static string Test(string threadName)
{
    WriteLine("开始运行...");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    Sleep(TimeSpan.FromSeconds(2));

    CurrentThread.Name = threadName;
    return $"线程名:{CurrentThread.Name}";
}

static string Test(out int threadId)
{
    WriteLine("开始运行...");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    Sleep(TimeSpan.FromSeconds(2));

    threadId = CurrentThread.ManagedThreadId;
    return $"线程池线程工作Id是:{threadId}";
}

运作结果如下图所示。

金沙注册送58 9

5.
5.2 并发容器与并发集合2

4.
合伙与锁关键字2

1.6 将EAP格局转换为天职

在上几章中有涉及,通过BackgroundWorker类经过事件的章程落成的异步,大家叫它EAP格局。那么怎么着将EAP方式转换为天职吗?很简短,大家只须求通过TaskCompletionSource类,即可将EAP情势转换为职分。

示范代码如下所示。

static void Main(string[] args)
{
    var tcs = new TaskCompletionSource<int>();

    var worker = new BackgroundWorker();
    worker.DoWork += (sender, eventArgs) =>
    {
        eventArgs.Result = TaskMethod("后台工作", 5);
    };

    // 通过此方法 将EAP模式转换为 任务
    worker.RunWorkerCompleted += (sender, eventArgs) =>
    {
        if (eventArgs.Error != null)
        {
            tcs.SetException(eventArgs.Error);
        }
        else if (eventArgs.Cancelled)
        {
            tcs.SetCanceled();
        }
        else
        {
            tcs.SetResult((int)eventArgs.Result);
        }
    };

    worker.RunWorkerAsync();

    // 调用结果
    int result = tcs.Task.Result;

    WriteLine($"结果是:{result}");

    ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务{name}运行在线程{CurrentThread.ManagedThreadId}上. 是否为线程池线程{CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));

    return 42 * seconds;
}

运作结果如下图所示。

金沙注册送58 10

6.
Future模式 2

5.
5.2 并发容器与并发集合2

1.7 实现撤销选项

在TAP情势中,完成裁撤选项和前面包车型大巴异步方式一样,都以利用CancellationToken来贯彻,不过分裂的是Task构造函数允许传入贰个CancellationToken,从而在职分实际运维在此之前撤除它。

以身作则代码如下所示。

static void Main(string[] args)
{
    var cts = new CancellationTokenSource();
    // new Task时  可以传入一个 CancellationToken对象  可以在线程创建时  变取消任务
    var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
    WriteLine(longTask.Status);
    cts.Cancel();
    WriteLine(longTask.Status);
    WriteLine("第一个任务在运行前被取消.");

    // 同样的 可以通过CancellationToken对象 取消正在运行的任务
    cts = new CancellationTokenSource();
    longTask = new Task<int>(() => TaskMethod("Task 2", 10, cts.Token), cts.Token);
    longTask.Start();

    for (int i = 0; i < 5; i++)
    {
        Sleep(TimeSpan.FromSeconds(0.5));
        WriteLine(longTask.Status);
    }
    cts.Cancel();
    for (int i = 0; i < 5; i++)
    {
        Sleep(TimeSpan.FromSeconds(0.5));
        WriteLine(longTask.Status);
    }

    WriteLine($"这个任务已完成,结果为{longTask.Result}");

    ReadLine();
}

static int TaskMethod(string name, int seconds, CancellationToken token)
{
    WriteLine($"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}");

    for (int i = 0; i < seconds; i++)
    {
        Sleep(TimeSpan.FromSeconds(1));
        if (token.IsCancellationRequested)
        {
            return -1;
        }
    }

    return 42 * seconds;
}

运转结果如下图所示,那里必要留意的是,若是是在职务执行此前撤废了职分,那么它的结尾状态是Canceled。假若是在执行进度中收回任务,那么它的情状是RanCompletion

金沙注册送58 11

7. 5.3 阻塞队列和生产者-消费者格局(5.3.2 串行线程封闭 5.3.3 双端队列与办事密取 2

6.
Future模式 2

1.8 处理职分中的分外

在任务中,处理十二分和别的异步方式处理十分类似,若是能在所发生非凡的线程中拍卖,那么毫无在别的地方处理。可是对于部分不可预料的分外,那么能够经过两种办法来处理。

能够通过拜访task.Result品质来拍卖至极,因为访问那特性情的Get措施会使当前线程等待直到该职务成功,并将充裕传播给当下线程,那样就足以因而try catch语句块来捕获分外。别的利用task.GetAwaiter().GetResult()措施和第使用task.Result看似,同样能够捕获分外。即使是要捕获八个职务中的相当错误,那么能够由此ContinueWith()措施来处理。

现实怎么着兑现,演示代码如下所示。

static void Main(string[] args)
{
    Task<int> task;
    // 在主线程中调用 task.Result task中的异常信息会直接抛出到 主线程中
    try
    {
        task = Task.Run(() => TaskMethod("Task 1", 2));
        int result = task.Result;
        WriteLine($"结果为: {result}");
    }
    catch (Exception ex)
    {
        WriteLine($"异常被捕捉:{ex.Message}");
    }
    WriteLine("------------------------------------------------");
    WriteLine();

    // 同上 只是访问Result的方式不同
    try
    {
        task = Task.Run(() => TaskMethod("Task 2", 2));
        int result = task.GetAwaiter().GetResult();
        WriteLine($"结果为:{result}");
    }
    catch (Exception ex)
    {
        WriteLine($"异常被捕捉: {ex.Message}");
    }
    WriteLine("----------------------------------------------");
    WriteLine();

    var t1 = new Task<int>(() => TaskMethod("Task 3", 3));
    var t2 = new Task<int>(() => TaskMethod("Task 4", 4));

    var complexTask = Task.WhenAll(t1, t2);
    // 通过ContinueWith TaskContinuationOptions.OnlyOnFaulted的方式 如果task出现异常 那么才会执行该方法
    var exceptionHandler = complexTask.ContinueWith(t => {
        WriteLine($"异常被捕捉:{t.Exception.Message}");
        foreach (var ex in t.Exception.InnerExceptions)
        {
            WriteLine($"-------------------------- {ex.Message}");
        }
    },TaskContinuationOptions.OnlyOnFaulted);

    t1.Start();
    t2.Start();

    ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));
    // 人为抛出一个异常
    throw new Exception("Boom!");
    return 42 * seconds;
}

运营结果如下所示,需求小心的是,假设在ContinueWith()艺术中抓获两个任务产生的极度,那么它的尤其类型是AggregateException,具体的万分音信包括在InnerExceptions个中,要小心和InnerException区分。

金沙注册送58 12

8. 5.4 不通方法与中断方法 2

7. 5.3 阻塞队列和生产者-消费者方式(5.3.2 串行线程封闭 5.3.3 双端队列与做事密取 2

1.9 互相运转职务

本节中要害介绍了八个点子的利用,八个是伺机组中全体职分都施行达成的Task.WhenAll()办法,另三个是假若组中一个主意执行完成都履行的Task.WhenAny()方法。

实际使用,如下演示代码所示。

static void Main(string[] args)
{
    // 第一种方式 通过Task.WhenAll 等待所有任务运行完成
    var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
    var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));

    // 当firstTask 和 secondTask 运行完成后 才执行 whenAllTask的ContinueWith
    var whenAllTask = Task.WhenAll(firstTask, secondTask);
    whenAllTask.ContinueWith(t => WriteLine($"第一个任务答案为{t.Result[0]},第二个任务答案为{t.Result[1]}"), TaskContinuationOptions.OnlyOnRanToCompletion);

    firstTask.Start();
    secondTask.Start();

    Sleep(TimeSpan.FromSeconds(4));

    // 使用WhenAny方法  只要列表中有一个任务完成 那么该方法就会取出那个完成的任务
    var tasks = new List<Task<int>>();
    for (int i = 0; i < 4; i++)
    {
        int counter = 1;
        var task = new Task<int>(() => TaskMethod($"Task {counter}",counter));
        tasks.Add(task);
        task.Start();
    }

    while (tasks.Count > 0)
    {
        var completedTask = Task.WhenAny(tasks).Result;
        tasks.Remove(completedTask);
        WriteLine($"一个任务已经完成,结果为 {completedTask.Result}");
    }

    ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));
    return 42 * seconds;
}

运营结果如下图所示。

金沙注册送58 13

9. 5.5 同步工具类 5.5.1 闭锁 5.5.2FutureTask5.5.3 信号量 5.5.4 栅栏 3

8. 5.4 绿灯方法与中断方法 2

1.10 使用TaskScheduler配置职分履行

Task中,负权利务调度是TaskScheduler指标,FCL提供了三个派生自TaskScheduler的类型:线程池职务调度器(Thread
Pool Task Scheduler)
同台上下文职务调度器(Synchronization
Scheduler)
。默许情况下全数应用程序都使用线程池义务调度器,不过在UI组件中,不使用线程池中的线程,幸免跨线程更新UI,要求运用同步上下文职务调度器。能够通超过实际施TaskSchedulerFromCurrentSynchronizationContext()静态方法来获得对一起上下文任务调度器的引用。

示范程序如下所示,为了延时联手上下文义务调度器,大家此次利用WPF来创设项目。

MainWindow.xaml 代码如下所示。

<Window x:Class="Recipe9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Recipe9"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBlock Name="ContentTextBlock" HorizontalAlignment="Left" Margin="44,134,0,0" VerticalAlignment="Top" Width="425" Height="40"/>
        <Button Content="Sync" HorizontalAlignment="Left" Margin="45,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonSync_Click"/>
        <Button Content="Async" HorizontalAlignment="Left" Margin="165,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonAsync_Click"/>
        <Button Content="Async OK" HorizontalAlignment="Left" Margin="285,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonAsyncOK_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs 代码如下所示。

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    // 同步执行 计算密集任务 导致UI线程阻塞
    private void ButtonSync_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;

        try
        {
            string result = TaskMethod().Result;
            ContentTextBlock.Text = result;
        }
        catch (Exception ex)
        {
            ContentTextBlock.Text = ex.InnerException.Message;
        }
    }

    // 异步的方式来执行 计算密集任务 UI线程不会阻塞 但是 不能跨线程更新UI 所以会有异常
    private void ButtonAsync_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;
        Mouse.OverrideCursor = Cursors.Wait;

        Task<string> task = TaskMethod();
        task.ContinueWith(t => {
            ContentTextBlock.Text = t.Exception.InnerException.Message;
            Mouse.OverrideCursor = null;
        }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
    }

    // 通过 异步 和 FromCurrentSynchronizationContext方法 创建了线程同步的上下文  没有跨线程更新UI 
    private void ButtonAsyncOK_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;
        Mouse.OverrideCursor = Cursors.Wait;
        Task<string> task = TaskMethod(TaskScheduler.FromCurrentSynchronizationContext());

        task.ContinueWith(t => Mouse.OverrideCursor = null,
            CancellationToken.None,
            TaskContinuationOptions.None,
            TaskScheduler.FromCurrentSynchronizationContext());
    }

    Task<string> TaskMethod()
    {
        return TaskMethod(TaskScheduler.Default);
    }

    Task<string> TaskMethod(TaskScheduler scheduler)
    {
        Task delay = Task.Delay(TimeSpan.FromSeconds(5));

        return delay.ContinueWith(t =>
        {
            string str = $"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}";

            Console.WriteLine(str);

            ContentTextBlock.Text = str;
            return str;
        }, scheduler);
    }
}

运作结果如下所示,从左至右依次单击按钮,前三个按钮将会引发这几个。
金沙注册送58 14

现实音信如下所示。

金沙注册送58 15

10. 5.6 营造火速且可伸缩的结果缓存3

9. 5.5 同步工具类 5.5.1 闭锁 5.5.2FutureTask5.5.3 信号量 5.5.4 栅栏 3

参照书籍

正文首要参考了以下几本书,在此对这个小编表示诚心的蒙恩被德,谢谢您们为.Net的发扬光大所做的贡献!

  1. 《CLR via C#》
  2. 《C# in Depth Third Edition》
  3. 《Essential C# 6.0》
  4. 《Multithreading with C# Cookbook Second Edition》
  5. 《C#二十四线程编制程序实战》

源码下载点击链接
演示源码下载

11.
线程池3

10. 5.6 营造高速且可伸缩的结果缓存3

小编水平有限,假设不当欢迎各位批评指正!

自然想趁待业时期的小时读完《Multithreading with C# Cookbook Second
艾德ition》那本书,并且享受做的相干笔记;可是出于小编近期职业规划和人体原因,可能近年来都尚龙时间来更新那个连串,没法完结几天一更。请大家多多包罗!可是笔者一定会将以此系列全体制改良进实现的!感激大家的支撑!

12.
7.1 职分撤消3

11.
线程池3

13.
职务并行库(TPL) 4

12.
7.1 职责废除3

14.
死锁的幸免与诊断4

13.
职务并行库(TPL) 4

15.
原子变量与非阻塞同步机制4

14.
死锁的防止与诊断4

16.
协程4

15.
原子变量与非阻塞同步机制4

17.
异步、二十八线程、职责、并行的面目4

16.
协程4

18.
今后,该用哪些来编排三十二线程 5

17.
异步、八线程、职分、并行的精神4

18.1.1.
1,异步编制程序5

18.
今日,该用怎么着来编排二十四线程 5

19. 响应式编制程序6

18.1.1.
1,异步编制程序5

20. ,数据流编制程序6

19. 响应式编制程序6

20.1. 5,Actor模型7

20. ,数据流编制程序6

21.
Qa7

20.1. 5,Actor模型7

22.
Java c#
.net c++的面世技术7

21.
Qa7

22.1.
Java并发编制程序实战(第一6届Jolt大奖提名图书,Java并发编制程序必读佳作8

22.
Java c#
.net c++的产出技术7

22.2.
Java并发技术8

22.1.
Java并发编制程序实战(第一6届Jolt大奖提名图书,Java并发编程必读佳作8

22.3.
《C#多线程编制程序实战( ((美…【8

22.2.
Java并发技术8

22.4.
Line 278:   《C++并发编制程序实战》 Line
285: 第叁章
你好,C++并发世界9

22.3.
《C#十二线程编制程序实战( ((美…【8

22.5.
《C#并发编制程序经典实例》9

22.4.
Line 278:   《C++并发编制程序实战》 Line
285: 第叁章 你好,C++并发世界9

1. 油但是生一般涉及如下多少个地点:

1. 多线程编制程序(已不合时宜,不介绍)

2. 异步编制程序

3. 互为编制程序

4. 响应式编制程序

5. 数据流编制程序

 

22.5.
《C#并发编制程序经典实例》9

2. 线程安全性 ( 2.2 原子性    2.3 加锁机制

 

1. 出现一般涉及如下多少个地点:

1. 多线程编制程序(已不合时宜,不介绍)

2. 异步编制程序

3. 并行编程

4. 响应式编制程序

5. 数据流编制程序

 

2.1. 线程封闭3.3.1Ad-hoc线程封闭   3.3.2 栈封闭   3.3.3ThreadLocal类

 

2. 线程安全性 ( 2.2 原子性    2.3 加锁机制

 

3. 异步

2.1. 线程封闭3.3.1Ad-hoc线程封闭   3.3.2 栈封闭   3.3.3ThreadLocal类

 

4. 合伙与锁关键字

3. 异步

5. 5.2 并发容器与并发集合

4. 联袂与锁关键字

6. Future模式

小编:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 Ake巴 阿尔 拉帕努伊 ) 

汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com

转发请申明来源: 

 

5. 5.2 并发容器与并发集合

7. 5.3 阻塞队列和劳动者-消费者形式(5.3.2 串行线程封闭 5.3.3 双端队列与办事密取

6. Future模式

作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 Ake巴 阿尔 拉帕努伊 ) 

汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com

转发请评释来源: 

 

8. 5.4 堵塞方法与中断方法

7. 5.3 阻塞队列和生产者-消费者形式(5.3.2 串行线程封闭 5.3.3 双端队列与做事密取

9. 5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask   5.5.3 信号量 5.5.4 栅栏

8. 5.4 梗阻方法与中断方法

10. 5.6 营造高速且可伸缩的结果缓存

9. 5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask   5.5.3 信号量 5.5.4 栅栏

11. 线程池

第⑦章 线程池的应用
8.1 在职分与实践政策之间的隐性耦合
8.1.1 线程饥饿死锁
8.1.2 运维时刻较长的职务
8.2 设置线程池的深浅
8.3 配置ThreadPoolExecutor
8.3.1 线程的成立与销毁
8.3.2 管理连串职责
8.3.3 饱和策略
8.3.4 线程工厂

 

 

10. 5.6 创设高效且可伸缩的结果缓存

12. 7.1 职分裁撤

7.1.1 中断
7.1.2 中断策略
7.1.3 响应中断
7.1.4 示例:计时运转
7.1.5 通过Future来完结打消
7.1.6 处理不可中断的隔绝
7.1.7 选用newTaskFor来封装非标准的打消
7.2 截至基于线程的劳务
7.2.1 示例:日志服务
7.2.2 关闭ExecutorService
7.2.3 “毒丸”对象
7.2.4 示例:只进行二次的劳动
7.2.5 shutdownNow的局限性
7.3 处理非平常的线程终止

11. 线程池

第捌章 线程池的选取
8.1 在职务与执行策略之间的隐性耦合
8.1.1 线程饥饿死锁
8.1.2 运行时刻较长的职分
8.2 设置线程池的轻重
8.3 配置ThreadPoolExecutor
8.3.1 线程的创设与销毁
8.3.2 管理类别义务
8.3.3 饱和策略
8.3.4 线程工厂

 

 

13. 职责并行库(TPL)

12. 7.1 职分打消

7.1.1 中断
7.1.2 中断策略
7.1.3 响应中断
7.1.4 示例:计时运营
7.1.5 通过Future来完成废除
7.1.6 处理不可中断的封堵
7.1.7 接纳newTaskFor来封装非标准化准的吊销
7.2 甘休基于线程的服务
7.2.1 示例:日志服务
7.2.2 关闭ExecutorService
7.2.3 “毒丸”对象
7.2.4 示例:只实行2回的劳务
7.2.5 shutdownNow的局限性
7.3 处理非寻常的线程终止

14. 死锁的制止与诊断

13. 职分并行库(TPL)

15. 原子变量与非阻塞同步机制

14. 死锁的防止与诊断

16. 协程

15. 原子变量与非阻塞同步机制

17. 异步、八线程、职责、并行的实质

那三个概念对应在CL酷路泽中的本质,本质都是二十三十二线程。

异步,简而言之就是BeginInvoke、EndInvoke方式,它在CLSportage内部线程池举行管理;

多线程,体现在C#中,能够由项目Thread发起。也足以由ThreadPool发起。前者不受CL兰德酷路泽线程池管理,后者则是。FCL团队为了各类编程模型的有益,还此外提供了BackgroundWorker和几何个Timer,基本上它们都以ThreadPool的滋长,扩展了有个别和调用者线程的互相功用;

职务(Task),为FCL4.0新增的职能,在二个叫作任务并行库(TPL)的地点,其实也便是System.Threading.Tasks命名空间下。义务并行库名字取的很神秘,其实它也是CL普拉多线程池的升高。优化了线程间的调度算法,扩展了和调用者线程的互相成效;

相互(Parallel),为FCL4.0新增的成效,也属于TPL。并行在后台使用Task进行田管,说白了,因为Task使用的线程池线程,所以Parallel自然使用的也是线程池线程实行保管,它的泰山真面目仅仅是尤为简化了Task。在此处要增强3个对于相互的明亮。实际上,多线程天然就是相互的。及时不用任务并行库,用Thread类型新起多少个线程,CL途乐或许说Windows系统也会将那三个线程依照需求配置到八个CPU上去执行。所以,并不是因为多了义务并行库,CL本田UR-V才支撑并行总计,任务并行库只是提供了一组API,使咱们能够更好的操纵线程举办交互开发而已。

 

16. 协程

18. 当今,该用哪些来编排四线程 

借使您在FRAMEWO帕杰罗K4.0下编写制定代码,那么相应依照那几个优先级来创作多线程代码: 

优先

次优先

不得以

Parallel(含扩展库PLinq)

Task

ThreadPool(BackgroundWorker,Timer)

异步

Thread

其一表满足了大多数景况下的八个优先级指点,但在好几意况下会有分裂。

三十二线程编制程序(已不合时宜,不介绍)

17. 异步、多线程、任务、并行的面目

那多少个概念对应在CLCRUISER中的本质,本质都是二十八线程。

异步,一句话来说就是BeginInvoke、EndInvoke情势,它在CL奥迪Q3内部线程池举办田管;

多线程,体现在C#中,能够由项目Thread发起。也足以由ThreadPool发起。前者不受CL途睿欧线程池管理,后者则是。FCL团队为了各样编制程序模型的福利,还此外提供了BackgroundWorker和多少个Timer,基本上它们都是ThreadPool的提升,扩展了有些和调用者线程的相互功用;

职分(Task),为FCL4.0新增的作用,在二个称作任务并行库(TPL)的地点,其实也正是System.Threading.Tasks命名空间下。任务并行库名字取的很神秘,其实它也是CLCR-V线程池的拉长。优化了线程间的调度算法,扩大了和调用者线程的并行功能;

互相(Parallel),为FCL4.0新增的成效,也属于TPL。并行在后台使用Task实行保管,说白了,因为Task使用的线程池线程,所以Parallel自然使用的也是线程池线程举办政管理制,它的原形仅仅是尤为简化了Task。在那里要抓实1个对于互相的通晓。实际上,多线程天然正是互相的。及时不用职务并行库,用Thread类型新起八个线程,CLRAV4只怕说Windows系统也会将那五个线程依据须求配置到多个CPU上去执行。所以,并不是因为多了任务并行库,CL安德拉才支撑并行计算,职务并行库只是提供了一组API,使大家能够更好的操纵线程实行交互开发而已。

 

18.0.1. 1,异步编制程序

异步编制程序便是接纳future方式(又称promise)恐怕回调机制来兑现(Non-blocking
on waiting)。

微软还尤其把异步编制程序分作了3种不一样的模型:基于职分的方式(TAP)便是小编上面推荐的那种,基于事件的方式(EAP)和异步编程模型(APM)小编上边不引进的风浪和回调。

 

18. 近日,该用怎么着来编排十二线程 

假定您在FRAMEWOPRADOK4.0下编写制定代码,那么应该遵循这几个优先级来写作多线程代码: 

优先

次优先

不得以

Parallel(含扩展库PLinq)

Task

ThreadPool(BackgroundWorker,Timer)

异步

Thread

那么些表满意了多数状态下的1个优先级辅导,但在一些情况下会有两样。

多线程编制程序(已不合时宜,不介绍)

19. 响应式编程

响应式编程近日成为了叁个Buzzword,其实微软6年前就开始给.NET提供一个Reactive 
Extensions
了。一开端要精晓响应式编制程序有点不方便,可是只要明白了,你就会对它的精锐功效爱不释手。一言以蔽之,响应式编制程序把事件流看作数据流,可是数量流是从IEnumable中拉取的,而数据流是从IObservable推送给您的。为何响应式编制程序能够兑现产出呢?那是因为奇骏x做到线程不可知,每一遍事件触发,后续的处理会从线程池中随意取出叁个线程来拍卖。且能够对事件设置窗口期和限流。举个例子,你能够用Lacrossex来让追寻文本框实行延期处理(而不用接近笔者很早的时候用个定时器来推迟了)。

18.0.1. 1,异步编制程序

异步编制程序正是行使future方式(又称promise)大概回调机制来贯彻(Non-blocking
on waiting)。

微软还特地把异步编制程序分作了3种差异的模型:基于职责的格局(TAP)正是自小编上面推荐的那种,基于事件的方式(EAP)和异步编制程序模型(APM)笔者上边不引进的风云和回调。

 

20. ,数据流编制程序

数据流(DataFlow)编制程序恐怕大家就更目生了,可是仍然有个别常用场景能够选取数据流来化解。数据流其实是在职分并行库(TPL)上衍生出来的一套处理数据的恢弘(也结合了异步的表征),TPL也是处理互相编制程序中任务并行和数码交互的基础库。

以管窥天,TPL
DataFlow正是对数码举行多重拍卖,首先为那样的处理定义一套网格(mesh),网格中能够定义分叉(fork)、连接(join)、循环(loop)。数据流入那样的拍卖网格就能够相互的被处理。你能够认为网格是一种升级版的管道,实际上很多时候纵然被当作管道来利用。使用处境可以是“分析文本文件中词频”,也能够是“拍卖生产者/消费者难题”。

 

19. 响应式编制程序

响应式编制程序近日变为了二个Buzzword,其实微软6年前就初始给.NET提供3个Reactive 
Extensions
了。一开头要清楚响应式编制程序有点不方便,但是假如明白了,你就会对它的无敌功效爱不释手。简单的讲,响应式编制程序把事件流看作数据流,不过数量流是从IEnumable中拉取的,而数据流是从IObservable推送给您的。为啥响应式编制程序能够实现产出呢?那是因为卡宴x做到线程不可见,每一回事件触发,后续的处理会从线程池中随心所欲取出1个线程来拍卖。且能够对事件设置窗口期和限流。举个例子,你能够用CRUISERx来让寻找文本框进行延期处理(而不用类似笔者很早的时候用个定时器来推迟了)。

20.1. 5,Actor模型

Scala有Akka,其实微软商量院也推出了Orleans来支持了Actor模型的贯彻,当然也有Akka.NET可用。Orleans设计的靶子是为了便利程序员开发供给广泛扩充的云服务,

 

 

20. ,数据流编制程序

数据流(DataFlow)编制程序只怕大家就更面生了,可是照旧有些常用场景能够应用数据流来消除。数据流其实是在职务并行库(TPL)上衍生出来的一套处理数据的扩展(也构成了异步的特征),TPL也是拍卖彼此编制程序中任务并行和多少交互的基础库。

以偏概全,TPL
DataFlow正是对数据进行连串处理,首先为如此的处理定义一套网格(mesh),网格中能够定义分叉(fork)、连接(join)、循环(loop)。数据流入那样的处理网格就能够相互的被拍卖。你可以认为网格是一种升级版的管道,实际上很多时候固然被作为管道来行使。使用情状能够是“浅析文本文件中词频”,也足以是“拍卖生产者/消费者难点”。

 

21. Qa

.2:何时用异步,几时用线程或线程池

那亟需从“IO操作的DMA(Direct Memory Access)形式”讲起。通过DMA的数据交流差不离能够不损耗CPU的能源。在硬件部分,硬盘、网卡、声卡、显卡等都有DMA成效。能够归纳的觉得,当我们的工作线程必要操作I/O能源的时候(如读取三个大文件、读取一个网页、读取Socke包等),大家就必要用异步去做这么些工作。异步格局只会在做事起来以及工作甘休的时候占用CL帕杰罗线程池,别的时候由硬盘、网卡等硬件装备来处理具体的工作,那就不会过多占用到CPU空间和岁月消耗。 

归纳而言:

计量密集型工作,直接选择线程;

IO密集型工作,采纳异步机制;

当大家不精通怎么工作是I/O密集型的,一个不是很适宜的教导便是:查看FCL类型成员,假如成员提供了类似BeginDosomething方法的,则优先采用它,而不是新起三个线程或丢到线程池。

 

3.4:何时用Thread 
以上的各样线程模型,它们最终都以Thread。 那么怎么着时候需求Thread直接出场呢?

最要紧的应用Thread的说辞是,大家需求控制线程的先行级。Thread之上的线程模型都不帮衬先行级设置。设置三个线程的高优先级能够使它得到更加多的CPU时间;

而且,能够操纵线程为前台线程。当然,由Thread新起的线程暗中认可正是前台线程。前台线程不趁着调用者线程的中止而中止,这使得大家能够用Thread来开始展览部分主体的操作。

 

20.1. 5,Actor模型

Scala有Akka,其实微软研商院也推出了Orleans来协助了Actor模型的贯彻,当然也有Akka.NET可用。Orleans设计的对象是为了便利程序员开发须求广大扩张的云服务,

 

 

22. Java c# .net c++的产出技术

21. Qa

.2:曾几何时用异步,曾几何时用线程或线程池

那需求从“IO操作的DMA(Direct Memory Access)方式”讲起。通过DMA的数据调换大概可以不损耗CPU的财富。在硬件部分,硬盘、网卡、声卡、显卡等都有DMA功用。能够省略的觉得,当大家的办事线程需求操作I/O财富的时候(如读取三个大文件、读取1个网页、读取Socke包等),大家就必要用异步去做那些事情。异步格局只会在工作起初以及工作甘休的时候占用CL瑞鹰线程池,此外时候由硬盘、网卡等硬件配备来拍卖具体的行事,这就不会过多占用到CPU空间和岁月消耗。 

席卷而言:

计量密集型工作,直接运用线程;

IO密集型工作,采取异步机制;

当大家不精晓怎么工作是I/O密集型的,3个不是很合适的点拨正是:查看FCL类型成员,要是成员提供了近似BeginDosomething方法的,则先行利用它,而不是新起三个线程或丢到线程池。

 

3.4:何时用Thread 
如上的各个线程模型,它们最后都以Thread。 那么如何时候须要Thread直接出场呢?

最重点的施用Thread的说辞是,我们要求控制线程的优先级。Thread之上的线程模型都不扶助先行级设置。设置三个线程的高优先级可以使它拿走更加多的CPU时间;

与此同时,能够控制线程为前台线程。当然,由Thread新起的线程默许就是前台线程。前台线程不随着调用者线程的暂停而暂停,那使得大家能够用Thread来举行局地宗旨的操作。

 

22.1. Java并发编制程序实战(第①6届Jolt大奖提名图书,Java并发编制程序必读佳作

作者:Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Doug Lea
著,童云兰 等译

 

 

第1章 简介

 第①章 线程安全性

 第叁章 对象的共享

 第肆章 对象的构成

 第6章 基础营造立模型块

 第五章 义务履行

 第八章 撤废与关闭

 第7章 线程池的利用

 第捌章 图形用户界面应用程序

 第拾章 制止活跃性危险

 第贰1章 质量与可伸缩性

 第③2章 并发程序的测试

 第13章 显式锁

 第②4章 塑造自定义的共同工具

 第二5章 原子变量与非阻塞同步机制

 第壹6章 Java内部存款和储蓄器模型

 

 

22. Java c# .net c++的产出技术

22.2. Java并发技术

Executor框架

 

22.1. Java并发编制程序实战(第二6届Jolt大奖提名图书,Java并发编制程序必读佳作

作者:Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Doug Lea 著,童云兰 等译

 

 

第1章 简介

 第②章 线程安全性

 第一章 对象的共享

 第四章 对象的三结合

 第⑥章 基础营造立模型块

 第六章 任务执行

 第⑦章 撤消与关闭

 第十章 线程池的采用

 第柒章 图形用户界面应用程序

 第柒章 制止活跃性危险

 第壹1章 品质与可伸缩性

 第壹2章 并发程序的测试

 第13章 显式锁

 第③4章 塑造自定义的联合工具

 第壹5章 原子变量与非阻塞同步机制

 第二6章 Java内部存款和储蓄器模型

 

 

22.3. 《C#二十四线程编制程序实战( ((美…【 

第一章 线程基础 ( lock关键字 1.11 使用Monitor类锁定能源
金沙注册送58 , 第二章 线程同步
 第二章 使用线程池
第陆章 使用职务并行库
第5章 使用C#
5.0
第⑥章 使用并发集合
第7章 使用PLINQ
第8章 使用Reactive
Extensions
第⑦章 使用异步I/O
第8章 并行编制程序情势
第21章 更加多音信

 

22.2. Java并发技术

Executor框架

 

22.4. Line 278:   《C++并发编制程序实战》 Line 285: 第三章 你好,C++并发世界 

Line 300: 第二章
管理线程

Line 311: 第三章
在线程间共享数据

Line 329: 第6章
同步出现操作

Line 348: 第六章
C++内部存款和储蓄器模型和原子

Line 370: 第五章
设计基于锁的面世数据结构

Line 380: 第⑩章
设计无锁的面世数据结构

 

22.3. 《C#多线程编制程序实战( ((美…【 

第①章 线程基础 ( lock关键字 1.11 使用Monitor类锁定财富
 第壹章 线程同步
 第一章 使用线程池
第五章 使用任务并行库
第5章 使用C#
5.0
第五章 使用并发集合
第7章 使用PLINQ
第8章 使用Reactive
Extensions
第7章 使用异步I/O
第8章 并行编制程序形式
第壹1章 更多新闻

 

22.5. 《C#并发编制程序经典实例》

 第一 章 并发编制程序概述  

第二 章 异步编制程序基础  

第② 章 并行开发的基础  

第伍 章 数据流基础  

第5 章 Rx 基础  

第⑤ 章 测试技术  

第7 章 互操作  

第8 章 集合  

第9 章 取消  

第10 章 函数式OOP

第11 章 同步  

第12 章 调度  

第①3 章 实用技巧  

参考资料

异步、多线程、职务、并行编制程序之一:采取12分的八线程模型

  • Luminji – 博客园.html

自作者干吗喜欢用C#来做并发编制程序-博客-云栖社区-Ali云.html

 

atiend

22.4. Line 278:   《C++并发编制程序实战》 Line 285: 第贰章 你好,C++并发世界 

Line 300: 第三章 管理线程

Line 311: 第①章 在线程间共享数据

Line 329: 第六章 同步出现操作

Line 348: 第四章 C++内部存款和储蓄器模型和原子

Line 370: 第四章 设计基于锁的面世数据结构

Line 380: 第捌章 设计无锁的面世数据结构

 

22.5. 《C#现身编制程序经典实例》

 第叁 章 并发编程概述  

第叁 章 异步编制程序基础  

第2 章 并行开发的基本功  

第5 章 数据流基础  

第5 章 Rx 基础  

第五 章 测试技术  

第7 章 互操作  

第8 章 集合  

第9 章 取消  

第10 章 函数式OOP

第11 章 同步  

第12 章 调度  

第三3 章 实用技巧  

参考资料

异步、二十四线程、任务、并行编制程序之一:接纳安妥的八线程模型

  • Luminji – 博客园.html

自己干吗喜欢用C#来做并发编制程序-博客-云栖社区-Ali云.html

 

atiend

 

相关文章

网站地图xml地图