经典的异步编程模型(IAsyncResult)

  • 最新的异步编程模型(async 和 await)
  • 将 IAsyncInfo 转换成 Task
  • 将 Task 转换成 IAsyncInfo

示例
1、使用经典的异步编程模型(IAsyncResult)实现一个支持异步操作的类
Thread/Async/ClassicAsync.cs

/*
* 使用经典的异步编程模型(IAsyncResult)实现一个支持异步操作的类
*/ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace XamlDemo.Thread.Async
{
public class ClassicAsync
{
private delegate string HelloDelegate(string name); private HelloDelegate _helloDelegate; public ClassicAsync()
{
_helloDelegate = new HelloDelegate(Hello);
} private string Hello(string name)
{
new ManualResetEvent(false).WaitOne(3000);
return "hello: " + name;
} // begin 方法
public IAsyncResult BeginRun(string name, AsyncCallback callback, Object state)
{
// 新开线程,去执行 Hello() 方法,callback 是回调,state 是上下文
return _helloDelegate.BeginInvoke(name, callback, state);
} // end 方法
public string EndRun(IAsyncResult ar)
{
if (ar == null)
throw new NullReferenceException("IAsyncResult 不能为 null"); return _helloDelegate.EndInvoke(ar);
}
}
}

Thread/Async/ClassicAsyncDemo.xaml

<Page
x:Class="XamlDemo.Thread.Async.ClassicAsyncDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Thread.Async"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> <Button Name="btnIAsyncResult" Content="IAsyncResult 的 Demo" Click="btnIAsyncResult_Click_1" Margin="0 10 0 0" /> </StackPanel>
</Grid>
</Page>

Thread/Async/ClassicAsyncDemo.xaml.cs

/*
* 演示如何通过经典的异步编程模型(IAsyncResult)来进行异步操作
*
* IAsyncResult - 异步操作结果
* AsyncState - 上下文
* IsCompleted - 异步操作是否已完成
* AsyncWaitHandle - 获取用于等待异步操作完成的 System.Threading.WaitHandle 对象(通过 WaitHandle.WaitOne() 在当前线程等待)
*/ using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace XamlDemo.Thread.Async
{
public sealed partial class ClassicAsyncDemo : Page
{
System.Threading.SynchronizationContext _syncContext; public ClassicAsyncDemo()
{
this.InitializeComponent(); // 获取当前 UI 线程
_syncContext = System.Threading.SynchronizationContext.Current;
} private void btnIAsyncResult_Click_1(object sender, RoutedEventArgs e)
{
ClassicAsync classicAsync = new ClassicAsync(); IAsyncResult ar = classicAsync.BeginRun("webabcd", new AsyncCallback(Callback), classicAsync); lblMsg.Text = "开始执行,3 秒后完成";
} private void Callback(IAsyncResult ar)
{
ClassicAsync classicAsync = (ClassicAsync)ar.AsyncState;
string result = classicAsync.EndRun(ar); _syncContext.Post(
(ctx) =>
{
lblMsg.Text = result;
},
null);
}
}
}

2、演示如何通过最新的异步编程模型(async 和 await)来进行异步操作
Thread/Async/NewAsyncDemo.xaml

<Page
x:Class="XamlDemo.Thread.Async.NewAsyncDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Thread.Async"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> <Button Name="btnTaskWithoutReturn" Content="执行一个不带返回值的 Task" Click="btnTaskWithoutReturn_Click_1" Margin="0 10 0 0" /> <Button Name="btnTaskWithReturn" Content="执行一个带返回值的 Task" Click="btnTaskWithReturn_Click_1" Margin="0 10 0 0" /> <Button Name="btnMultiTask" Content="并行执行多个 Task" Click="btnMultiTask_Click_1" Margin="0 10 0 0" /> <Button Name="btnTaskWithoutAwait" Content="执行一个不 await 的 Task" Click="btnTaskWithoutAwait_Click_1" Margin="0 10 0 0" /> </StackPanel>
</Grid>
</Page>

Thread/Async/NewAsyncDemo.xaml.cs

/*
* 演示如何通过最新的异步编程模型(async 和 await)来进行异步操作
*
* 注:
* 1、要想 await,其所在方法必须标记为 async
* 2、方法被标记为 async 是为了让编译器重新编写该方法,使 await 中的内容重新编写为具有 GetAwaiter() 等实际异步逻辑的代码
*/ using System;
using System.Threading;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace XamlDemo.Thread.Async
{
public sealed partial class NewAsyncDemo : Page
{
private static int _count = 0; public NewAsyncDemo()
{
this.InitializeComponent();
} // 不带返回值的 Task
private async Task TaskWithoutReturn()
{
// 在另一个线程 sleep 1000 毫秒,然后回到 UI 线程
await Task.Delay(1000);
// await Task.Delay(Timeout.Infinite); 长眠于此
// await Task.Delay(Timeout.InfiniteTimeSpan); 长眠于此 // 直接在当前线程 sleep 可以使用如下方法,因为 WinRT 中没有 Thread.Sleep() 了
// new ManualResetEvent(false).WaitOne(1000); Interlocked.Increment(ref _count);
} // 带返回值的 Task
private async Task<int> TaskWithReturn()
{
await Task.Delay(1000);
Interlocked.Increment(ref _count); return _count;
} // 演示不带返回值的异步操作
private async void btnTaskWithoutReturn_Click_1(object sender, RoutedEventArgs e)
{
// ConfigureAwait(false) - 异步操作后不返回 UI 线程,可节省一点点资源。默认值:ConfigureAwait(true)
await TaskWithoutReturn().ConfigureAwait(false);
lblMsg.Text = "count: " + _count.ToString();
} // 演示带返回值的异步操作
private async void btnTaskWithReturn_Click_1(object sender, RoutedEventArgs e)
{
int result = await TaskWithReturn();
lblMsg.Text = "count: " + result.ToString();
} // 演示多任务并行执行的异步操作
private async void btnMultiTask_Click_1(object sender, RoutedEventArgs e)
{
Task task = Task.WhenAll(TaskWithoutReturn(), TaskWithoutReturn(), TaskWithoutReturn()); DateTime dt = DateTime.Now; await task; lblMsg.Text = "count: " + _count.ToString() + ", 执行时间: " + (DateTime.Now - dt).TotalSeconds.ToString() + "秒";
} // 演示如何执行一个不 await 的 Task
private void btnTaskWithoutAwait_Click_1(object sender, RoutedEventArgs e)
{
// 让 task 在新线程执行去吧,本线程不管它是什么执行情况
Task task = TaskWithoutReturn();
lblMsg.Text = "count: " + _count.ToString();
}
}
}

3、演示如何将 IAsyncInfo(IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, IAsyncOperationWithProgress) 转成 Task
Thread/Async/IAsyncInfo2Task.xaml

<Page
x:Class="XamlDemo.Thread.Async.IAsyncInfo2Task"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Thread.Async"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> </StackPanel>
</Grid>
</Page>

Thread/Async/IAsyncInfo2Task.xaml.cs

/*
* 演示如何将 IAsyncInfo(IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, IAsyncOperationWithProgress) 转成 Task
*/ using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace XamlDemo.Thread.Async
{
public sealed partial class IAsyncInfo2Task : Page
{
public IAsyncInfo2Task()
{
this.InitializeComponent();
} protected async override void OnNavigatedTo(NavigationEventArgs e)
{
// 用于取消 Task
CancellationTokenSource cts = new CancellationTokenSource(); // 创建一个 IAsyncInfo
IAsyncOperation<int> action = AsyncInfo.Run<int>(
(token) =>
Task.Run<int>(
() =>
{
token.WaitHandle.WaitOne(3000);
token.ThrowIfCancellationRequested(); return 10 * 10;
},
token)); lblMsg.Text = "开始执行,3 秒后完成"; // 将 IAsyncOperation 转换成 Task
// AsTask() 是扩展方法,其逻辑在 System.WindowsRuntimeSystemExtensions 类中
Task<int> task = action.AsTask<int>(cts.Token);
int result = await task; lblMsg.Text = "结果:" + result.ToString();
}
}
}

4、演示如何将 Task 转成 IAsyncInfo(IAsyncAction, IAsyncOperation)
Thread/Async/Task2IAsyncInfo.xaml

<Page
x:Class="XamlDemo.Thread.Async.Task2IAsyncInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Thread.Async"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> </StackPanel>
</Grid>
</Page>

Thread/Async/Task2IAsyncInfo.xaml.cs

/*
* 演示如何将 Task 转成 IAsyncInfo(IAsyncAction, IAsyncOperation)
*/ using System;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace XamlDemo.Thread.Async
{
public sealed partial class Task2IAsyncInfo : Page
{
public Task2IAsyncInfo()
{
this.InitializeComponent();
} protected async override void OnNavigatedTo(NavigationEventArgs e)
{
// 用于取消 IAsyncInfo(注意:本例中的 IAsyncInfo 是从 Task 转换过来的,所以 IAsyncInfo.Cancel() 方法无效)
CancellationTokenSource cts = new CancellationTokenSource(); // 创建一个 Task
Task<int> task = Task.Run<int>(
() =>
{
cts.Token.WaitHandle.WaitOne(3000);
cts.Token.ThrowIfCancellationRequested(); return 10 * 10;
},
cts.Token); lblMsg.Text = "开始执行,3 秒后完成"; // 将 Task 转换成 IAsyncOperation
// AsAsyncAction(), AsAsyncOperation() 是扩展方法,其逻辑在 System.WindowsRuntimeSystemExtensions 类中
IAsyncOperation<int> operation = task.AsAsyncOperation<int>();
int result = await operation; lblMsg.Text = "结果:" + result.ToString();
}
}
}

多线程之异步编程: 经典和最新的异步编程模型,async与await的更多相关文章

  1. 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换

    [源码下载] 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换 作者:webabcd 介绍 ...

  2. 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换

    经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...

  3. 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)

    一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并 ...

  4. 最新Python异步编程详解

    我们都知道对于I/O相关的程序来说,异步编程可以大幅度的提高系统的吞吐量,因为在某个I/O操作的读写过程中,系统可以先去处理其它的操作(通常是其它的I/O操作),那么Python中是如何实现异步编程的 ...

  5. C#的多线程——使用async和await来完成异步编程(Asynchronous Programming with async and await)

    https://msdn.microsoft.com/zh-cn/library/mt674882.aspx 侵删 更新于:2015年6月20日 欲获得最新的Visual Studio 2017 RC ...

  6. Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别

    Task C# 多线程和异步模型 TPL模型   Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...

  7. 《C#并发编程经典实例》学习笔记—异步编程关键字 Async和Await

    C# 5.0 推出async和await,最早是.NET Framework 4.5引入,可以在Visual Studio 2012使用.在此之前的异步编程实现难度较高,async使异步编程的实现变得 ...

  8. [书籍]用UWP复习《C#并发编程经典实例》

    1. 简介 C#并发编程经典实例 是一本关于使用C#进行并发编程的入门参考书,使用"问题-解决方案-讨论"的模式讲解了以下这些概念: 面向异步编程的async和await 使用TP ...

  9. 《C#并发编程经典实例》笔记

    1.前言 2.开宗明义 3.开发原则和要点 (1)并发编程概述 (2)异步编程基础 (3)并行开发的基础 (4)测试技巧 (5)集合 (6)函数式OOP (7)同步 1.前言 最近趁着项目的一段平稳期 ...

随机推荐

  1. 阅读微信支付demo收获

       1,公司现有系统有很多,存放重要接口的日志分布在不同的库,每个系统都有单独的日志采集表,日志采集模块:        ????         这些日志可以统一放到一个地方,通过一个组件提供出去 ...

  2. 微信js框架第二篇(创建完整界面布局)

    接着昨天的继续谈关于微信新出的这个js框架,今天主要谈一个页面的创建到布局的详细步骤. 一.创建一个完整页面       页面你可以创建在项目的任何节点,只要你在入口文件正确引入创建该页面的路径就可使 ...

  3. 【Spring】SpringMVC中浅析Date类型数据的传递

    在控制器中加入如下代码: @InitBinder public void initBinder(ServletRequestDataBinder bin){ SimpleDateFormat sdf ...

  4. ABP Zero示例项目登录报错“Empty or invalid anti forgery header token.”问题解决

    ABP Zero项目,登录时出现如图"Empty or invalid anti forgery header token."错误提示的解决方法: 在 WebModule.cs的P ...

  5. 9.2.4 .net core 通过ViewComponent封装控件

    我们在.net core中还使用了ViewComponent方式生成控件.ViewComponent也是asp.net core的新特性,是对页面部分的渲染,以前PartialView的功能,可以使用 ...

  6. dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】

    最近维护的系统切换了网络环境,由联通换成了电信网络,因为某些过滤规则导致系统连不上zookeeper服务器(应用系统机器在深圳,网络为电信线路,zookeeper服务器在北京,网络为联通线路),因为我 ...

  7. 让IIS7.0.0.0支持 .iso .7z .torrent .apk等文件下载的设置方法

    IIS默认支持哪些MIME类型呢,我们可以这样查看:打开IIS管理器(计算机--管理--服务和应用程序--Internet信息服务(IIS)管理器:或者Win+R,输入inetmgr,Enter),在 ...

  8. 用 Excel 测试“绘制两点间连线”的算法

    最近在研究和制作数字示波器,其中涉及一个小算法:需要将 ADC 采样的数值在 TFT LCD 屏幕上面显示并且用“线”连接起来. ADC 按照时序对输入电压采样后,记录的是一个个的数值,如果显示的时候 ...

  9. 释放Android的函数式能量(I):Kotlin语言的Lambda表达式

    原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...

  10. Eclipse for Java EE软件操作集锦(一)

    以下是我在Java网站开发过程中,关于软件操作Eclipse中,遇到的一些问题并提供了解决方案.一.java web开发使用的集成开发工具是eclipse for Java EE 官方下载地址:htt ...