服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#异步迭代IAsyncEnumerable应用实现

C#异步迭代IAsyncEnumerable应用实现

2022-11-23 11:57鲁广广 C#

IAsyncEnumerable可以来实现异步迭代,本文就主要介绍了C#异步迭代IAsyncEnumerable应用实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近用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 + "
";

            }
        }

     /// <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());
            }
        }

来看效果

C#异步迭代IAsyncEnumerable应用实现

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

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

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

C#异步迭代IAsyncEnumerable应用实现

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

比如改成这样

C#异步迭代IAsyncEnumerable应用实现

但是,这样一次就返回一组 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;
            }
        }

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

C#异步迭代IAsyncEnumerable应用实现

我们可以看到,不仅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;
        }

效果展示:

C#异步迭代IAsyncEnumerable应用实现

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

到此这篇关于C#异步迭代IAsyncEnumerable应用实现的文章就介绍到这了,更多相关C#异步迭代IAsyncEnumerable内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/luguangguang/p/14931794.html

延伸 · 阅读

精彩推荐
  • C#Unity3D 单例模式和静态类的使用详解

    Unity3D 单例模式和静态类的使用详解

    这篇文章主要介绍了Unity3D 单例模式和静态类的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    EZhex19916932022-11-13
  • C#一篇文章说通C#中的异步迭代器

    一篇文章说通C#中的异步迭代器

    这篇文章主要给大家介绍了如何通过一篇文章说通C#中的异步迭代器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    老王Plus的老王8892022-10-24
  • C#解析C#中的常量及如何在C#编程中定义常量

    解析C#中的常量及如何在C#编程中定义常量

    这篇文章主要介绍了C#中的常量及如何在C#编程中定义常量,是C#入门学习中的基础知识,需要的朋友可以参考下...

    C#教程网8662021-11-09
  • C#C# 文件安全管理需要注意的

    C# 文件安全管理需要注意的

    这篇文章主要介绍了C# 文件安全管理需要注意的,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...

    彭泽090211062022-11-08
  • C#用Linq从一个集合选取几列得到一个新的集合(可改列名)

    用Linq从一个集合选取几列得到一个新的集合(可改列名)

    这篇文章主要介绍了用Linq从一个集合选取几列得到一个新的集合(可改列名),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习...

    森大科技8002022-08-11
  • C#WPF中的ListBox实现按块显示元素的方法

    WPF中的ListBox实现按块显示元素的方法

    这篇文章主要介绍了WPF中的ListBox实现按块显示元素的方法,涉及ListBox属性设置相关操作技巧,需要的朋友可以参考下...

    永远爱好写程序8842021-12-07
  • C#dotnet core链接mongodb代码实例

    dotnet core链接mongodb代码实例

    这篇文章主要介绍了dotnet core链接mongodb代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考...

    mlh14215282022-08-11
  • C#C#自定义基于控制台的Timer实例

    C#自定义基于控制台的Timer实例

    这篇文章主要介绍了C#自定义基于控制台的Timer实现方法,可以简单模拟timer控件的相关功能,具有一定参考借鉴价值,需要的朋友可以参考下...

    北风其凉9812021-10-19