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

时间:2021-12-05 04:44:28

[源码下载]

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

作者:webabcd

介绍
重新想象 Windows 8 Store Apps 之 异步编程

  • 经典的异步编程模型(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();
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 = ; public NewAsyncDemo()
{
this.InitializeComponent();
} // 不带返回值的 Task
private async Task TaskWithoutReturn()
{
// 在另一个线程 sleep 1000 毫秒,然后回到 UI 线程
await Task.Delay();
// 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();
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();
token.ThrowIfCancellationRequested(); return * ;
},
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();
cts.Token.ThrowIfCancellationRequested(); return * ;
},
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();
}
}
}

OK
[源码下载]

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

  1. 重新想象 Windows 8 Store Apps &lpar;42&rpar; - 多线程之线程池&colon; 延迟执行&comma; 周期执行&comma; 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  2. 重新想象 Windows 8 Store Apps &lpar;43&rpar; - 多线程之任务&colon; Task 基础&comma; 多任务并行执行&comma; 并行运算(Parallel)

    [源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...

  3. 重新想象 Windows 8 Store Apps &lpar;45&rpar; - 多线程之异步编程&colon; IAsyncAction&comma; IAsyncOperation&comma; IAsyncActionWithProgress&comma; IAsyncOperationWithProgress

    [源码下载] 重新想象 Windows 8 Store Apps (45) - 多线程之异步编程: IAsyncAction, IAsyncOperation, IAsyncActionWithPro ...

  4. 重新想象 Windows 8 Store Apps &lpar;46&rpar; - 多线程之线程同步&colon; Lock&comma; Monitor&comma; Interlocked&comma; Mutex&comma; ReaderWriterLock

    [源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...

  5. 重新想象 Windows 8 Store Apps &lpar;47&rpar; - 多线程之线程同步&colon; Semaphore&comma; CountdownEvent&comma; Barrier&comma; ManualResetEvent&comma; AutoResetEvent

    [源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...

  6. 重新想象 Windows 8 Store Apps &lpar;48&rpar; - 多线程之其他辅助类&colon; SpinWait&comma; SpinLock&comma; Volatile&comma; SynchronizationContext&comma; CoreDispatcher&comma; ThreadLocal&comma; ThreadStaticAttribute

    [源码下载] 重新想象 Windows 8 Store Apps (48) - 多线程之其他辅助类: SpinWait, SpinLock, Volatile, SynchronizationCont ...

  7. 重新想象 Windows 8 Store Apps 系列文章索引

    [源码下载][重新想象 Windows 8.1 Store Apps 系列文章] 重新想象 Windows 8 Store Apps 系列文章索引 作者:webabcd 1.重新想象 Windows ...

  8. 重新想象 Windows 8 Store Apps &lpar;34&rpar; - 通知&colon; Toast Demo&comma; Tile Demo&comma; Badge Demo

    [源码下载] 重新想象 Windows 8 Store Apps (34) - 通知: Toast Demo, Tile Demo, Badge Demo 作者:webabcd 介绍重新想象 Wind ...

  9. 重新想象 Windows 8 Store Apps &lpar;35&rpar; - 通知&colon; Toast 详解

    [源码下载] 重新想象 Windows 8 Store Apps (35) - 通知: Toast 详解 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 通知 Toa ...

随机推荐

  1. MyEclipse配置Tomcat 6

    打开首选项 禁用MyEclipse自带的Tomcat 6 下载apache-tomcat-6.0.29.tar.gz 地址:http://yunpan.cn/cKg6kq2RmjdUB  提取码 98 ...

  2. UvaLive 5026 Building Roads

    传送门 Time Limit: 3000MS Description There is a magic planet in the space. There is a magical country ...

  3. nasm预处理器&lpar;4&rpar;

    nasm定义了一套标准宏,当开始处理源文件时,这些宏都已经被定义了,如果希望程序在执行前没有预定义的宏存在,可以使用%clear清空预处理器的一切宏. __NASM_MAJOR__ 主版本号 __NA ...

  4. 把 java web application deploy 到 root

    http://*.com/questions/5328518/deploying-my-application-at-the-root-in-tomcat You have a ...

  5. js 延时

    alert(1);setTimeout(function(){alert(2);}, 1000);setTimeout(function(){alert(3);}, 2000);

  6. CCPC 2017-2018&comma; Finals Solution

    A - Dogs and Cages 水. #include <bits/stdc++.h> using namespace std; int t; double n; int main( ...

  7. 20145311 《Java程序设计》第5周学习总结

    20145311 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 8.1语法与继承结构 8.1.1Try.catch java中所有的错误都会打包为对象,可以try catc ...

  8. Effective STL 阅读笔记: Item 3&colon; Make copying cheap and correct for objects in containers

    容器 (Containers) 用来存储对象 (Objects), 但是被存储的对象却并非原原本本是你给他的那一个, 而是你指定对象的一个拷贝.而后续对该容器内存储对象的操作,大多也是基于拷贝的. 拷 ...

  9. python爬虫解析库之re模块

    re模块 一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中, ...

  10. java基础02

    使用 myeclipse写第一个java程序 之后  右键 点击 src  创建 Class /** * package:包的声明! * 代表我们当前的java源文件在项目中的位置! * 必须位于除了 ...