VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • SynchronizationContext(同步上下文)综述(2)

 的作用类似于 Defalut 同步上下文 ,将 Task 在 ThreadPool 中列队。
  • 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)

    ObserveOn 、 SubscribeOn 和 SynchronizationContextScheduler

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

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

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

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

    7.5. 异步编程 Async

    await 、 ConfigureAwait 、 SwitchTo 和 Progress<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同步上下文 上执行

    返回 void 的 async 方法

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

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

    8. 限制和功能

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

    如果您认为这篇文章还不错或者有所收获,您可以通过右边的"打赏"功能 打赏我一杯咖啡【物质支持】,也可以点击左下角的【好文要顶】按钮【精神支持】,因为这两种支持都是我继续写作,分享的最大动力!

    作者: 大师兄石头


    
    相关教程
    关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号