博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程之异步编程: 经典和最新的异步编程模型,async与await
阅读量:7250 次
发布时间:2019-06-29

本文共 8798 字,大约阅读时间需要 29 分钟。

经典的异步编程模型(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

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

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
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

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
action = AsyncInfo.Run
( (token) => Task.Run
( () => { token.WaitHandle.WaitOne(3000); token.ThrowIfCancellationRequested(); return 10 * 10; }, token)); lblMsg.Text = "开始执行,3 秒后完成"; // 将 IAsyncOperation 转换成 Task // AsTask() 是扩展方法,其逻辑在 System.WindowsRuntimeSystemExtensions 类中 Task
task = action.AsTask
(cts.Token); int result = await task; lblMsg.Text = "结果:" + result.ToString(); } }}

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

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
task = Task.Run
( () => { cts.Token.WaitHandle.WaitOne(3000); cts.Token.ThrowIfCancellationRequested(); return 10 * 10; }, cts.Token); lblMsg.Text = "开始执行,3 秒后完成"; // 将 Task 转换成 IAsyncOperation // AsAsyncAction(), AsAsyncOperation() 是扩展方法,其逻辑在 System.WindowsRuntimeSystemExtensions 类中 IAsyncOperation
operation = task.AsAsyncOperation
(); int result = await operation; lblMsg.Text = "结果:" + result.ToString(); } }}

转载于:https://www.cnblogs.com/ansen312/p/5943258.html

你可能感兴趣的文章
MySQL 数据库的备份与恢复
查看>>
Android中的设计模式之单例模式
查看>>
使用Cordova将您的前端JavaScript应用打包成手机原生应用
查看>>
用Python玩转微信
查看>>
Bootstrap 小结
查看>>
《JavaScript权威指南》——JavaScript核心
查看>>
C语言 时间函数的学习
查看>>
你真的懂Redis事务吗?
查看>>
收藏 | 12个ggplot2拓展程序助你强化R可视化
查看>>
1-Linux C语言编程基本原理与实践-学习笔记
查看>>
WRF-DA代码编译与安装(二)——WRF-DA模块的编译与安装
查看>>
2018年美团Android校招
查看>>
Spring消息之WebSocket
查看>>
Java 文件流操作.
查看>>
《11招玩转网络安全》之第三招:Web暴力破解-Low级别
查看>>
Eclipse快捷键大全
查看>>
Android实现TextView字符串波浪式跳动
查看>>
NumPy—random随机数生成函数总结
查看>>
第10章节-Python3.5-Django路由分发
查看>>
排序三 直接插入排序
查看>>