最近用WPF做金税盘开发中有这样一个需求,批量开票每次开票都需要连接一次金税盘。

比如我有发票 a, b ,c ,d e 这五张发票,每次开具发票都需要调用金税盘底层,才能正常开票。

首先,尝试写第一个方法

 private  void Button_Click(object sender, RoutedEventArgs e)
{
var dateStart = DateTime.Now; //记录用时的起始时间
DebugText = string.Empty;
List<string> fpList = new List<string>() { "a", "b", "c", "d" }; foreach (var item in MockIO)
{
var dateEnd = DateTime.Now;
var timeSpan = dateEnd - dateStart;//记录开票用时
DebugText += item + " " + timeSpan.TotalSeconds + "\r\n"; }
} /// <summary>
/// 批量开票方法
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
public static IEnumerable<string> MockIO(List<string> ls)
{ foreach (var item in ls)
{
Task.Delay(1000).Wait();
yield return item;
Debug.WriteLine(Thread.GetCurrentProcessorId());
}
}

来看效果

很明显,发生了UI阻塞情况。因为我们并未对代码做任何异步处理。接下来,我们开始尝试修改。

首先,我们尝试按照常规异步方法修改 MockIO 函数,增加 async 关键词,返回结果增加 Task, 内部对IO操作添加 await。

修改完毕后,编译并没有通过,VS对该方法报异常

通过提示信息,我们可以发现,返回值 Task<IEnumerable<string>> 并不是可以迭代的,因为我们采用了 yield 来返回值,所以我们需要一个可以迭代的返回值。

比如改成这样

但是,这样一次就返回一组 Task ,没有用到方便的 yield;

此时,就可以用到 IAsyncEnumerable 来设计了,IAsyncEnumerable是C# 8.0引入的新特性,在异步迭代中,非常方便。如上述代码,可以直接修改为

  public static async IAsyncEnumerable<string> MockIOAsync(List<string> ls)
{
foreach (var item in ls)
{
Task<Task<string>> task = Task<Task<string>>.Factory.StartNew(async () =>
{
await Task.Delay(1000);
return item; }); yield return await task.Result;
}
}

我们再运行调试,看一下效果

我们可以看到,不仅UI没有被阻塞,同时,传回的值也是一个接一个的传过来的,符合我们的预期。

扩展:虽然上述步骤我们完成的UI的非阻塞的实现,但是我们整个开票用时并没有节省。

接下来,我将继续修改 MockIOAsync 方法,将实现迭代器内部的多线程操作。

修改后的代码如下

    public static async Task<IEnumerable<string>> MockIOPerformanceAsync(List<string> ls)
{
List<string> lss = new List<string>();
List<Task> tasks = new List<Task>();
foreach (var item in ls)
{ Task task = new Task(() =>
{
Task.Delay(1000).Wait();
Debug.WriteLine(Thread.GetCurrentProcessorId());
lss.Add(item);
});
tasks.Add(task);
task.Start(); }
foreach (var item in tasks)
{
await item;
}
return lss;
}

效果展示:

嗯,速度很快,但是排序乱了,因为此方法在遍历中新建了线程,list 添加并不保证按照迭代器的顺序添加。有得有失。

自动判断
中文
中文(简体)
中文(香港)
中文(繁体)
英语
日语
朝鲜语
德语
法语
俄语
泰语
南非语
阿拉伯语
阿塞拜疆语
比利时语
保加利亚语
加泰隆语
捷克语
威尔士语
丹麦语
第维埃语
希腊语
世界语
西班牙语
爱沙尼亚语
巴士克语
法斯语
芬兰语
法罗语
加里西亚语
古吉拉特语
希伯来语
印地语
克罗地亚语
匈牙利语
亚美尼亚语
印度尼西亚语
冰岛语
意大利语
格鲁吉亚语
哈萨克语
卡纳拉语
孔卡尼语
吉尔吉斯语
立陶宛语
拉脱维亚语
毛利语
马其顿语
蒙古语
马拉地语
马来语
马耳他语
挪威语(伯克梅尔)
荷兰语
北梭托语
旁遮普语
波兰语
葡萄牙语
克丘亚语
罗马尼亚语
梵文
北萨摩斯语
斯洛伐克语
斯洛文尼亚语
阿尔巴尼亚语
瑞典语
斯瓦希里语
叙利亚语
泰米尔语
泰卢固语
塔加路语
茨瓦纳语
土耳其语
宗加语
鞑靼语
乌克兰语
乌都语
乌兹别克语
越南语
班图语
祖鲁语

自动选择
中文
中文(简体)
中文(香港)
中文(繁体)
英语
日语
朝鲜语
德语
法语
俄语
泰语
南非语
阿拉伯语
阿塞拜疆语
比利时语
保加利亚语
加泰隆语
捷克语
威尔士语
丹麦语
第维埃语
希腊语
世界语
西班牙语
爱沙尼亚语
巴士克语
法斯语
芬兰语
法罗语
加里西亚语
古吉拉特语
希伯来语
印地语
克罗地亚语
匈牙利语
亚美尼亚语
印度尼西亚语
冰岛语
意大利语
格鲁吉亚语
哈萨克语
卡纳拉语
孔卡尼语
吉尔吉斯语
立陶宛语
拉脱维亚语
毛利语
马其顿语
蒙古语
马拉地语
马来语
马耳他语
挪威语(伯克梅尔)
荷兰语
北梭托语
旁遮普语
波兰语
葡萄牙语
克丘亚语
罗马尼亚语
梵文
北萨摩斯语
斯洛伐克语
斯洛文尼亚语
阿尔巴尼亚语
瑞典语
斯瓦希里语
叙利亚语
泰米尔语
泰卢固语
塔加路语
茨瓦纳语
土耳其语
宗加语
鞑靼语
乌克兰语
乌都语
乌兹别克语
越南语
班图语
祖鲁语

有道翻译
百度翻译
谷歌翻译
谷歌翻译(国内)

翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 百度翻译

自动判断
中文
中文(简体)
中文(香港)
中文(繁体)
英语
日语
朝鲜语
德语
法语
俄语
泰语
南非语
阿拉伯语
阿塞拜疆语
比利时语
保加利亚语
加泰隆语
捷克语
威尔士语
丹麦语
第维埃语
希腊语
世界语
西班牙语
爱沙尼亚语
巴士克语
法斯语
芬兰语
法罗语
加里西亚语
古吉拉特语
希伯来语
印地语
克罗地亚语
匈牙利语
亚美尼亚语
印度尼西亚语
冰岛语
意大利语
格鲁吉亚语
哈萨克语
卡纳拉语
孔卡尼语
吉尔吉斯语
立陶宛语
拉脱维亚语
毛利语
马其顿语
蒙古语
马拉地语
马来语
马耳他语
挪威语(伯克梅尔)
荷兰语
北梭托语
旁遮普语
波兰语
葡萄牙语
克丘亚语
罗马尼亚语
梵文
北萨摩斯语
斯洛伐克语
斯洛文尼亚语
阿尔巴尼亚语
瑞典语
斯瓦希里语
叙利亚语
泰米尔语
泰卢固语
塔加路语
茨瓦纳语
土耳其语
宗加语
鞑靼语
乌克兰语
乌都语
乌兹别克语
越南语
班图语
祖鲁语

自动选择
中文
中文(简体)
中文(香港)
中文(繁体)
英语
日语
朝鲜语
德语
法语
俄语
泰语
南非语
阿拉伯语
阿塞拜疆语
比利时语
保加利亚语
加泰隆语
捷克语
威尔士语
丹麦语
第维埃语
希腊语
世界语
西班牙语
爱沙尼亚语
巴士克语
法斯语
芬兰语
法罗语
加里西亚语
古吉拉特语
希伯来语
印地语
克罗地亚语
匈牙利语
亚美尼亚语
印度尼西亚语
冰岛语
意大利语
格鲁吉亚语
哈萨克语
卡纳拉语
孔卡尼语
吉尔吉斯语
立陶宛语
拉脱维亚语
毛利语
马其顿语
蒙古语
马拉地语
马来语
马耳他语
挪威语(伯克梅尔)
荷兰语
北梭托语
旁遮普语
波兰语
葡萄牙语
克丘亚语
罗马尼亚语
梵文
北萨摩斯语
斯洛伐克语
斯洛文尼亚语
阿尔巴尼亚语
瑞典语
斯瓦希里语
叙利亚语
泰米尔语
泰卢固语
塔加路语
茨瓦纳语
土耳其语
宗加语
鞑靼语
乌克兰语
乌都语
乌兹别克语
越南语
班图语
祖鲁语

有道翻译
百度翻译
谷歌翻译
谷歌翻译(国内)

翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 百度翻译

C#异步迭代 IAsyncEnumerable 应用的更多相关文章

  1. ES6-11学习笔记--异步迭代

    ES9提供异步迭代: for await of Symbol.asyncIterator   function getPromise(time) { return new Promise((resol ...

  2. C# 8 中的异步迭代器 IAsyncEnumerable<T> 解析

    异步编程已经流行很多年了,.NET 引入的 async 和 await 关键词让异步编程更具有可读性,但有一个遗憾,在 C# 8 之前都不能使用异步的方式处理数据流,直到 C# 8 引入的 IAsyn ...

  3. 一文说通C#中的异步迭代器

    今天来写写C#中的异步迭代器 - 机制.概念和一些好用的特性   迭代器的概念 迭代器的概念在C#中出现的比较早,很多人可能已经比较熟悉了. 通常迭代器会用在一些特定的场景中. 举个例子:有一个for ...

  4. ES6 Generators的异步应用

    ES6 Generators系列: ES6 Generators基本概念 深入研究ES6 Generators ES6 Generators的异步应用 ES6 Generators并发 通过前面两篇文 ...

  5. 深入Asyncio(十)异步解析式

    Async Comprehensions 目前已经学会了如何在Python中进行异步迭代,接下来的问题是这是否适用于解析式?答案是OJBK!该支持在PEP 530中提及,建议去读一下. >> ...

  6. [译]Python中的异步IO:一个完整的演练

    原文:Async IO in Python: A Complete Walkthrough 原文作者: Brad Solomon 原文发布时间:2019年1月16日 翻译:Tacey Wong 翻译时 ...

  7. 【JS】336- 拆解 JavaScript 中的异步模式

    点击上方"前端自习课"关注,学习起来~ JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS ...

  8. 【JS】285- 拆解 JavaScript 中的异步模式

    JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS.我最初接触不同的异步模式时,曾想当然的觉得 promise ...

  9. 聊一聊C# 8.0中的await foreach

    AsyncStreamsInCShaper8.0 很开心今天能与大家一起聊聊C# 8.0中的新特性-Async Streams,一般人通常看到这个词表情是这样. 简单说,其实就是C# 8.0中支持aw ...

随机推荐

  1. 操作系统中的进程同步与Window中利用内核对象进行线程同步的关系

    操作系统中为了解决进程间同步问题提出了用信号量机制,信号量可分为四种类型分别是互斥型信号量,记录型信号量,AND型信号量,信号量集. 互斥型信号量 互斥型信号量是资源数量为1的特殊的记录型信号量.表示 ...

  2. 简单介绍下自动化框架:Robot Framework

    一.简介: Robot Framework:Robot Framework是由Python编写的一款功能丰富并且扩展性强的自动化测试框架,也可以在Java和 .NET 上运行. HttpRunner: ...

  3. pytorch实现LeNet5分类CIFAR10

    关于LeNet-5 LeNet5的Pytorch实现在网络上已经有很多了,这里记录一下自己的实现方法. LeNet-5出自于Gradient-Based Learning Applied to Doc ...

  4. 百万级数据mysql查询优化

    一.limit越往后越慢的原因 当我们使用limit来对数据进行分页操作的时,会发现:查看前几页的时候,发现速度非常快,比如 limit 200,25,瞬间就出来了.但是越往后,速度就越慢,特别是百万 ...

  5. gitlab的CI/CD实现

    环境准备: gitlab账号公网账号:代码仓库和编译器 目标机:装有docker和gitlab-runner环境的服务器(Linux或类unix机器,我使用的时centos 项目代码:testgola ...

  6. (全解析)屏幕尺寸,分辨率,像素,PPI之间到底什么关系?

    (全解析)屏幕尺寸,分辨率,像素,PPI之间到底什么关系? 产品经理马忠信关注 22015.08.30 13:59:20字数 2,660阅读 52,661 今天我给大家来讲讲这几个咱们经常打交道的词到 ...

  7. 小白菜Windows10系统安装Linux(ubuntu)虚拟机超详细教程(全)

    注:本文"(         )"中的内容可忽略 1.下载VMware(威睿 计算机虚拟化软件) 官方下载地址 默认为最新版15.1.0,我们选择立即下载 (找一个比较大的盘不要是 ...

  8. k8s集群部署(2)

    一.利用ansible部署kubernetes准备阶段 1.集群介绍 基于二进制方式部署k8s集群和利用ansible-playbook实现自动化:二进制方式部署有助于理解系统各组件的交互原理和熟悉组 ...

  9. xshell 终端 中文乱码

    我们在终端输入命令,中文显示乱码了. 解决方案:将xshell 传输采用的默认encode改为utf-8 解决:

  10. element-ui 的el-select如何不显示value,显示value对应的label值

    有时根据需要,我们根据v-model的值绑定option, 想要的效果: 实际的效果: 原因: value的格式存在问题,数据库读取到的数据不一定为number类型,需要手动转换. 第一种 <t ...