SynchronizationContext(同步上下文)综述

>>返回《C# 并发编程》

  • 1. 概述
  • 2. 同步上下文 的必要性
    • 2.1. ISynchronizeInvoke 的诞生
    • 2.2. SynchronizationContext 的诞生
  • 3. 同步上下文 的概念
  • 4. 同步上下文 的实现
    • 4.1. WinForm 同步上下文
    • 4.2. Dispatcher 同步上下文
    • 4.3. Default 同步上下文
    • 4.4. 上下文捕获和执行
    • 4.5. AspNetSynchronizationContext
  • 5. 同步上下实现类 的注意事项
  • 6. AsyncOperationManager 和 AsyncOperation
  • 7. 同步上下文 的Library支持示例
    • 7.1. WCF
    • 7.2. Workflow Foundation (WF)
    • 7.3. Task Parallel Library (TPL)
    • 7.4. Reactive Extensions (Rx)
    • 7.5. 异步编程 Async
  • 8. 限制和功能

1. 概述

无论是什么平台(ASP.NET 、WinForm 、WPF 等),所有 .NET 程序都包含 同步上下文 概念,并且所有多线程编程人员都可以通过理解和应用它获益。

2. 同步上下文 的必要性

2.1. ISynchronizeInvoke 的诞生

  • 原始多线程

    • 多线程程序在 .NET Framework 出现之前就存在了。
    • 这些程序通常需要一个线程将一个工作单元传递给另一个线程
    • Windows 程序围绕消息循环进行,因此很多编程人员使用这一内置队列传递工作单元
    • 每个要以这种方式使用 Windows 消息队列的多线程程序都必须自定义 Windows 消息以及处理约定
  • ISynchronizeInvoke 的诞生
    • .NET Framework 首次发布时,这一通用模式是标准化模式。
    • 那时 .NET 唯一支持的 GUI 应用程序类型是 WinFrom。
    • 不过,框架设计人员期待其他模型,他们开发出了一种通用的解决方案,ISynchronizeInvoke 诞生了。
  • ISynchronizeInvoke 的原理
    • 一个“源”线程可以将一个委托列入“目标”线程队列。
    • ISynchronizeInvoke 还提供了一个属性来确定当前代码是否已在目标线程上运行。
    • WinForm 提供了单例的 ISynchronizeInvoke 实现,并且开发了一种模式来设计异步组件

2.2. SynchronizationContext 的诞生

  • ASP.NET 异步页面

    • .NET Framework 2.0 版包含很多重大改动。 其中一项重要改进是在 ASP.NET 体系结构中引入了异步页面

      • 在 .NET Framework 2.0 之前的版本中,每个 ASP.NET 请求都需要一个线程,线程会直到该请求完成
      • 这会造成线程利用率低下,因为创建网页通常依赖于数据库查询和 Web 服务调用,并且处理请求的线程必须等待,直到所有这些操作结束。
      • 后来使用异步页面,处理请求的线程可以开始每个操作,然后返回到 ASP.NET 线程池;当操作结束时,ASP.NET 线程池的另一个线程可以完成该请求
    • ISynchronizeInvoke 不太适合 ASP.NET 异步页面体系结构。
      • 使用 ISynchronizeInvoke 模式开发的异步组件在 ASP.NET 页面内无法正常工作,因为 ASP.NET 异步页面不与单个线程关联。
      • 需要设计出,无须将工作排入原来的线程队列,异步页面只需对未完成的操作进行计数 以确定页面请求何时可以完成。
  • 经过精心设计, SynchronizationContext 取代了 ISynchronizeInvoke

3. 同步上下文 的概念

ISynchronizeInvoke 满足了两点需求:

  1. 确定是否必须同步
  2. 使工作单元从一个线程列队等候另一个线程。

设计 SynchronizationContext 是为了替代 ISynchronizeInvoke ,但完成设计后,它就不仅仅是一个替代品了。

  • 一方面SynchronizationContext 提供了一种方式,可以使工作单元列队并列入上下文

    • 请注意,工作单元是列入上下文,而不是某个特定线程。
    • 这一区别非常重要,因为很多 SynchronizationContext 实现都不是基于单个特定线程的。
    • SynchronizationContext 不包含用来确定是否必须同步的机制,因为这是不可能的。
      • WPF 中的Dispatcher.Invoke是将委托列入上下文,不等委托执行直接返回
      • WinForm 中的txtUName.Invoke会启动一个process,等到委托执行完毕后返回
  • 另一方面,每个线程都有当前同步上下文
    • 线程上下文不一定唯一
    • 上下文实例可以与多个其他线程共享
    • 线程可以更改其当前上下文,但这样的情况非常少见。
  • 第三个方面,保持了未完成操作的计数。
    • 这样,就可以用于 ASP.NET 异步页面和需要此类计数的任何其他主机。
    • 大多数情况下,捕获到当前 SynchronizationContext 时,计数递增
      • 捕获到的 SynchronizationContext 用于将完成通知列队到上下文中时,计数递减 void OperationCompleted()
  • 其他一些方面,这些对大多数编程人员来说并不那么重要
// SynchronizationContext API的重要方面
class SynchronizationContext
{

  // 将工作分配到上下文中
  void Post(..); // (asynchronously 异步)

  void Send(..); // (synchronously 同步)

  // 跟踪异步操作的数量。
  void OperationStarted();

  void OperationCompleted();

  // 每个线程都有一个Current Context。
  // 如果“Current”为null,则按照惯例,
  // 最开始的当前上下文为 new SynchronizationContext()。
  static SynchronizationContext Current { get; }

  //设置当前同步上下文
  static void SetSynchronizationContext(SynchronizationContext);
}

4. 同步上下文 的实现

不同的框架和主机可以自行定义上下文

通过了解这些不同的实现及其限制,可以清楚了解 SynchronizationContext 概念可以不可以实现的功能

4.1. WinForm 同步上下文

位于:System.Windows.Forms.dll:System.Windows.Forms

WinForm

  • WinForm应用程序会创建并安装一个 WindowsFormsSynchronizationContext

    • 作为创建 UI Control 的每个线程的当前上下文
    • 一个 WinForm 应用程序对应一个同步上下文
  • 这一 SynchronizationContext 使用 UI ControlInvoke 等方法(ISynchronizeInvoke派生出来的),该方法将委托传递给基础 Win32 消息循环
  • WindowsFormsSynchronizationContext 的上下文是一个单例的 UI 线程
  • WindowsFormsSynchronizationContext 列队的所有委托一次一个地执行
    • 这个已排序的委托队列,被一个特定 UI 线程执行完

4.2. Dispatcher 同步上下文

位于:WindowsBase.dll:System.Windows.Threading

WPF

  • 委托按“Normal”优先级在 UI 线程的 Dispatcher 中列队
  • 当一个线程通过调用 Dispatcher.Run 开启 循环调度器 时,将这个初始化完成的 同步上下文 安装到当前上下文
  • DispatcherSynchronizationContext 的上下文是一个单独的 UI 线程。
  • 排队到 DispatcherSynchronizationContext 的所有委托均由特定的UI线程一次一个按其排队的顺序执行
  • 当前实现为每个顶层窗口创建一个 DispatcherSynchronizationContext,即使它们都使用相同的基础调度程序也是如此。

4.3. Default 同步上下文

调度线程池线程的同步上下文。

位于:mscorlib.dll:System.Threading

Default SynchronizationContext 是默认构造的 SynchronizationContext 对象。

  • 根据惯例,如果一个线程的当前 SynchronizationContext 为 null,那么它隐式具有一个Default SynchronizationContext
  • Default SynchronizationContext 将其异步委托列队到 ThreadPool ,但在调用线程上直接执行其同步委托
  • 因此,Default SynchronizationContext涵盖所有 ThreadPool 线程以及任何调用 Send 的线程。
  • 这个上下文“借助”调用 Send线程们,将这些线程放入这个上下文,直至委托执行完成
    • 从这种意义上讲,默认上下文可以包含进程中的所有线程
  • Default SynchronizationContext 应用于 线程池 线程,除非代码由 ASP.NET 承载。
  • Default SynchronizationContext 还隐式应用于显式子线程(Thread 类的实例),除非子线程设置自己的 SynchronizationContext

因此,UI 应用程序通常有两个同步上下文:

  • 包含 UI 线程的 UI SynchronizationContext
  • 包含 ThreadPool 线程的Default SynchronizationContext

4.4. 上下文捕获和执行

BackgroundWorker运行流程

  • 首先BackgroundWorker 捕获使用调用 RunWorkerAsync 的线程的 同步上下文
  • 然后,在Default SynchronizationContext中执行DoWork
  • 最后,在之前捕获的上下文中执行其 RunWorkerCompleted 事件

UI同步上下文 中只有一个 BackgroundWorker ,因此 RunWorkerCompletedRunWorkerAsync 捕获UI同步上下文中执行(如下图)。

UI同步上下文中的嵌套 BackgroundWorker

  • 嵌套: BackgroundWorker 从其 DoWork 处理程序启动另一个 BackgroundWorker

    • 嵌套的 BackgroundWorker 不会捕获 UI同步上下文
  • DoWork线程池 线程使用 默认同步上下文 执行。
    • 在这种情况下,嵌套的 RunWorkerAsync 将捕获默认 SynchronizationContext
    • 因此它将由一个 线程池 线程而不是 UI线程 执行其 RunWorkerCompleted
    • 这样会导致异步执行完后,后面的代码就不在UI同步上下文中执行了(如下图)。

默认情况下,控制台应用程序Windows服务 中的所有线程都只有 Default SynchronizationContext,这会导致一些基于事件异步组件失败(也就是没有UI同步上下文的特性)

  • 要解决这个问题,可以创建一个显式子线程,然后将 UI同步上下文 安装在该线程上,这样就可以为这些组件提供上下文。
  • Nito.Async 库的 ActionThread 类可用作通用同步上下文实现。

4.5. AspNetSynchronizationContext

位于:System.Web.dll:System.Web [internal class]

ASP.NET

  • SynchronizationContext线程池线程执行页面代码安装完成。
  • 当一个委托列入到捕获AspNetSynchronizationContext 中时,它设置原始页面的 identity 和 culture 到此线程,然后直接执行委托
    • 即使委托是通过调用 Post “异步”列入的,也会直接调用委托。

从概念上讲, AspNetSynchronizationContext 的上下文非常复杂。

  • 在异步页面的生命周期中,该同步上下文从来自 ASP.NET 线程池的一个线程开始。

    • 异步请求开始后,该上下文不包含任何线程。
    • 异步请求结束时,线程池线程进入该上下文并执行 处理完成的相关工作
  • 这可能是启动请求的线程,但更可能是操作完成时处于空闲状态的任何线程
  • 如果同一应用程序的多项操作同时完成, AspNetSynchronizationContext 确保一次只执行其中一项。它们可以在任意线程上执行,但该线程将具有原始页面的 identity 和 culture。

一个常见的示例:

在异步网页中使用 WebClient.DownloadDataAsync 将捕获当前 SynchronizationContext ,之后在该上下文中执行其 DownloadDataCompleted 事件。

  • 当页面开始执行时,ASP.NET 会分配一个线程执行该页面中的代码。
  • 该页面可能调用 DownloadDataAsync ,然后返回;
    • ASP.NET 对未完成的异步操作进行计数,以便了解页面处理是否已完成。
  • WebClient 对象下载所请求的数据后,它将在线程池线程上收到通知
    • 该线程将在捕获的上下文中引发 DownloadDataCompleted
  • 该上下文将保持在相同的线程中,但会确保事件处理的运行使用正确的 identity 和 culture 运行

5. 同步上下实现类 的注意事项

  • SynchronizationContext 提供了一种途径,可以在很多不同框架中编写组件

    • BackgroundWorkerWebClient 就是两个在 WinFormWPFConsoleASP.NET Application中同样应用自如的组件。
  • 在设计这类可重用组件时,必须注意几点:
    • 同步上下文的实现们不是平等可比的。

      • 这意味着没有类似 ISynchronizeInvoke.InvokeRequired 的等效项

        • 此属性确定在对如Concrol对象进行方法调用时,调用方是否必须通过 Invoke 进行调用(传入委托)。
        • 这样的(Control)对象被绑定到特定线程,并且不是线程安全的。
        • 如果要从其他线程调用对象的方法,则必须借助 Invoke 方法将对相应线程调用的委托列队
      • 不过,这不是多大的缺点;代码更为清晰,并且更容易验证它是否始终在已知上下文中执行,而不是试图处理多个上下文。
    • 不是所有 同步上下文的实现 都可以保证委托执行顺序或委托同步顺序。
      • UI同步上下文 满足上述条件
      • ASP.NET同步上下文 只提供同步
      • Default同步上下文 不保证执行顺序或同步顺序
    • 同步上下文实例线程之间没有 1:1 的对应关系
      • WindowsFormsSynchronizationContext 确实 1:1 映射到一个线程(只要不调用 SynchronizationContext.CreateCopy

        • 任何其他实现都不是这样
      • 一般而言,最好不要假设任何上下文实例将在任何指定线程上运行
    • SynchronizationContext.Post 方法不一定是异步的
      • 大多数实现异步实现此方法,但 AspNetSynchronizationContext 是一个明显的例外
      • 这可能会导致无法预料的重入问题

同步上下文实现类的摘要

使用特定线程 执行委托 独占 (一次执行一个委托) 有序 (委托按队列顺序执行) Send 可以直接调用委托 Post 可以直接调用委托
Winform 如果从UI线程调用 从不
WPF/Silverlight 如果从UI线程调用 从不
Default 不能 不能 不能 Always 从不
ASP.NET 不能 不能 Always Always

6. AsyncOperationManager 和 AsyncOperation

  • AsyncOperationManagerAsyncOperation 类是 SynchronizationContext 抽象类的轻型包装

    • AsyncOperation的异步是使用抽象的同步上下文进行封装的
  • AsyncOperationManager 在第一次创建 AsyncOperation捕获当前同步上下文 ,如果当前同步上下文为null,则使用 Default 同步上下文
  • AsyncOperation 将委托异步发布到捕获的 同步上下文
  • 大多数基于事件的异步组件都在其实现中使用 AsyncOperationManagerAsyncOperation
    • 这些对于具有明确完成点的异步操作非常有效

      • 即异步操作从一个点开始,以另一个点的事件结束
    • 其他异步通知可能没有明确的完成点;它们可能是一种订阅类型,在一个点开始,然后无限期持续
      • 对于这些类型的操作,当触发了被订阅的事件,在事件处理中直接捕获使用同步上下文

新组件不应使用基于事件的异步模式

  • 使用基于Task的异步模式

    • 组件返回 Task 和 Task 对象,而不是通过 同步上下文 引发事件
    • 基于 Task 的 API 是 .NET 中异步编程的发展方向

7. 同步上下文 的Library支持示例

  • BackgroundWorkerWebClient 这样的简单组件是隐式自带的

    • 隐藏了对同步上下文的捕获和使用。
  • 很多 Libraries 以更可见的方式使用 同步上下文
    • 通过使用 SynchronizationContext 公开 API,Libraries 不仅获得了框架独立性,而且为高级最终用户提供了一个可扩展点。
  • ExecutionContext
    • 是与执行的逻辑线程相关的所有信息提供单个容器。 这包括安全上下文调用上下文同步上下文
    • 任何捕获线程的 ExecutionContext 的系统都会捕获当前 同步上下文
    • 当恢复 ExecutionContext 时,通常也会恢复 同步上下文

7.1. WCF

WCF 有两个用于配置服务器和客户端行为的特性:

  • ServiceBehaviorAttributeCallbackBehaviorAttribute

    • 这两个特性都有一个 Boolean 属性:UseSynchronizationContext
    • 此特性的默认值为 true,这表示在创建通信通道时捕获当前 同步上下文 ,这一捕获的 同步上下文 用于使约定方法列队。
  • 服务器使用 Default 同步上下文
  • 客户端回调使用相应的 UI 同步上下文
  • 在需要重入时,这会导致问题,如客户端调用的服务器方法回调客户端方法。在这类情况下,将 UseSynchronizationContext 设置为 false 可以禁止 WCF 自动使用 同步上下文
    • 因为如果这时如果客户端使用的是UI同步上下文,可能造成不可预期的问题

7.2. Workflow Foundation (WF)

  • WorkflowInstance 类及其派生的 WorkflowApplication 类的SynchronizationContext 属性
  • 如果承载进程创建自己拥有的 WorkflowInstance ,同步上下文也许直接设置了
  • WorkflowInvoker.InvokeAsync 也使用 同步上下文
    • 它捕获当前 同步上下文 并将其传递给其 internalWorkflowApplication

      • 该 同步上下文 用于 Post 工作流完成事件以及工作流活动

7.3. Task Parallel Library (TPL)

TaskScheduler.FromCurrentSynchronizationContext

TPL 使用 Task 对象作为其工作单元并通过 TaskScheduler 执行。

  • 默认 TaskScheduler 的作用类似于 Defalut 同步上下文 ,将 TaskThreadPool 中列队。
  • TPL 队列还提供了另一个 TaskScheduler ,将 Task 在 一个同步上下文 中列队
    • UI 进度条更新 可以在一个嵌套 Task 中完成,如下所示。

UI 进度条更新


private void button1_Click(object sender, EventArgs e)
{
  // 捕获当前 SynchronizationContext 的 TaskScheduler.
  TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  // Start a new task (this uses the default TaskScheduler,
  // so it will run on a ThreadPool thread).
  Task.Factory.StartNew(() =>
  {
    // We are running on a ThreadPool thread here.
    // Do some work.
    // Report progress to the UI.
    Task reportProgressTask = Task.Factory.StartNew(() =>
    {
      // We are running on the UI thread here.
      // Update the UI with our progress.
    },CancellationToken.None,
      TaskCreationOptions.None,
      taskScheduler);

    reportProgressTask.Wait();
    // Do more work.
  });
}

CancellationToken.Register

  • CancellationToken 类可用于任意类型的取消操作
  • 为了与现有取消操作形式集成,该类允许注册委托以在请求取消时调用
    • 当取消委托被注册后,同步上下文就可以传递了

      • 当发起取消请求时, CancellationToken 将该委托列入 同步上下文 队列,然后才会进行执行

7.4. Reactive Extensions (Rx)

ObserveOnSubscribeOnSynchronizationContextScheduler

Rx 是一个库,它将事件视为数据流

  • ObserveOn(context) 运算符通过一个 同步上下文 将事件列队
  • SubscribeOn(context) 运算符通过一个 同步上下文 将对这些事件的订阅 列队
  • ObserveOn(context) 通常用于使用传入事件更新 UI,SubscribeOn 用于从 UI 对象使用事件

Rx 还有它自己的工作单元列队方法: IScheduler 接口。

  • Rx 包含 SynchronizationContextScheduler

    • 是一个将 Task 列入指定 同步上下文 的 IScheduler 实现。
    • 构造方法: SynchronizationContextScheduler(SynchronizationContext context)

7.5. 异步编程 Async

awaitConfigureAwaitSwitchToEventProgress<T>

  • 默认情况下, 当前同步上下文 在一个 await 关键字处被捕获
  • 同步上下文 用于在运行到 await关键字后时恢复
    • 也就是 await 关键字后面的执行代码会被列入到 该同步上下文 中执行

      • 仅当它不为 null 时,才捕获当前 同步上下文
      • 如果为 null ,则捕获当前 TaskScheduler
private async void button1_Click(object sender, EventArgs e)
{
  // 当前 SynchronizationContext 被 await 在暗中捕获
  var data = await webClient.DownloadStringTaskAsync(uri);

  // 此时,已捕获的SynchronizationContext用于恢复执行,
  // 因此我们可以自由更新UI对象。
}
  • ConfigureAwait 提供了一种途径避免 SynchronizationContext 捕获;

    • continueOnCapturedContext 参数传递 false 会阻止 await后的代码,在 await 执行前的 同步上下文 上执行
  • 同步上下文实例还有一种扩展方法 SwitchTo
    • 使用该方法,任何 async 的方法 可以通过调用 SwitchTo 改变到一个不同的同步上下文上,并 awaiting 结果

报告异步操作进展的通用模式:

  • IProgress<T> 接口及其实现 Progress<T>

    • 该类在构造时捕获 当前同步上下文
    • 并在中引发其 ProgressChanged 事件
    • 所以实例化时,需要在 UI同步上下文 上执行

返回 voidasync 方法

  • 在异步操作开始时递增计数
  • 在异步操作结束后递减计数

这一行为使返回 voidasync 方法 类似于顶级异步操作。

8. 限制和功能

  • 了解 同步上下文 对任何编程人员来说都是有益的
  • 现有跨框架组件使用它同步其事件
  • Libraries 可以将它公开以获得更高的灵活性
  • 技术精湛的编程人员了解 同步上下文 限制和功能后,可以更好地编写和利用这些类

原文地址:https://www.cnblogs.com/BigBrotherStone/p/12240731.html

时间: 2024-10-13 23:34:43

SynchronizationContext(同步上下文)综述的相关文章

ExecutionContext(执行上下文)综述

>>返回<C# 并发编程> 1. 简介 2. 同步异步对比 3. 上下文的捕获和恢复 4. Flowing ExecutionContext vs Using SynchronizationContext 5. 如何适用于 async/await 5.1. 实现方式 5.1.1. ExecutionContext 5.1.2. SynchronizationContext 5.2. 执行过程 5.2.1. SynchronizationContext 使用和控制 5.2.2. Ex

网络游戏同步问题综述

http://blog.csdn.net/yxriyin/article/details/23377271 最近看了比较多的网络同步问题因为我只做过回合制,没做过arpg,所以稍微去看看大致是怎么实现的.基本上可以归为两个问题:玩家位置同步和战斗指令同步.玩家位置同步的情况要比战斗指令同步的情况简单,不过正因为如此,你为了更好的同步,就会采取复杂的同步策略.另外,这两种同步其实是息息相关的,战斗肯定会涉及到位置判断.所以我打算一起思考这两个问题. 首先我们要知道在arpg游戏中,是需要对时协议的

[C#] 多线程(结合进度条)

线程生命周期(源w3cschool) 未启动状态:当线程实例被创建但Start方法未被调用时的状况. 就绪状态:当线程准备好运行并等待CPU周期时的状况. 不可运行状态: 已经调用Sleep方法 已经调用Wait方法 通过I/O操作阻塞 死亡状态:当线程已完成执行或已中止时的状况. Thread常用方法: public void Interrupt()    中断处于WaitSleepJoin线程状态的线程. public void Join()           在继续执行标准的COM和Se

[C#] 多线程总结(结合进度条)

线程生命周期 未启动状态:当线程实例被创建但 Start 方法未被调用时的状况. 就绪状态:当线程准备好运行并等待 CPU 周期时的状况. 不可运行状态: 已经调用 Sleep 方法 已经调用 Wait 方法 通过 I/O 操作阻塞 死亡状态:当线程已完成执行或已中止时的状况. Thread 常用方法: public void Interrupt()    中断处于 WaitSleepJoin 线程状态的线程. public void Join()         在继续执行标准的 COM 和

C#中的多线程 - 同步基础

原文:http://www.albahari.com/threading/part2.aspx 1同步概要 在第 1 部分:基础知识中,我们描述了如何在线程上启动任务.配置线程以及双向传递数据.同时也说明了局部变量对于线程来说是私有的,以及引用是如何在线程之间共享,允许其通过公共字段进行通信. 下一步是同步(synchronization):为期望的结果协调线程的行为.当多个线程访问同一个数据时,同步尤其重要,但是这是一件非常容易搞砸的事情. 同步构造可以分为以下四类: 简单的阻塞方法 这些方法

SynchronizationContext笔记

SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型还简化了托管应用程序为在不同的同步环境下正常工作而必须遵循的一些要求.同步模型的提供程序可以扩展此类并为这些方法提供自己的实现. 简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线程都附加Syn

.NET面试题解析(07)-多线程编程与线程同步

系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等,本文只是从常见面试题的角度(也是开发过程中常用)去深入浅出线程相关的知识.如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的比较好. 常见面试题目: 1. 描述线程与进程的区别? 2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题? 3. 简述后台线程和前台线程的区别? 4. 说说常

SynchronizationContext一篇

SynchronizationContext context; 最近写代码用到了这个,特别记录一下. 作用如下: // 摘要: // 提供在各种同步模型中传播同步上下文的基本功能. public class SynchronizationContext { ...... } 来自using System.Threading;这个命名空间,一看很熟悉是线程的大类命名空间. // 摘要: // 获取当前线程的同步上下文. // // 返回结果: // 一个 System.Threading.Sync

C#中的多线程 - 同步基础 z

原文:http://www.albahari.com/threading/part2.aspx 专题:C#中的多线程 1同步概要Permalink 在第 1 部分:基础知识中,我们描述了如何在线程上启动任务.配置线程以及双向传递数据.同时也说明了局部变量对于线程来说是私有的,以及引用是如何在线程之间共享,允许其通过公共字段进行通信. 下一步是同步(synchronization):为期望的结果协调线程的行为.当多个线程访问同一个数据时,同步尤其重要,但是这是一件非常容易搞砸的事情. 同步构造可以