C# 中 async/await 的这种用法以前被发现过吗? [关闭]

2023-11-24

在我之前在 stackoverflow 上提出了关于 async/await 的问题之后,在我看来,await 比营销建议的更强大、更通用。这似乎是构建计算表达式的通用方法,就像在 F# 中一样。因此,经过一番努力,我想出了一些成功执行的代码,如下所示。

    using FluentAssertions;
    using System.Collections.Generic;

    namespace EnumerableViaAwait.Specs
    {
        [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestClass]
        public class MyTestClass
        {
            public IEnumerable<int> Numbers()
            {
                return EnumeratorMonad.Build<int>(async Yield =>
                {
                    await Yield(11);
                    await Yield(22);
                    await Yield(33);
                });
            }

            [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
            public void TestEnum()
            {
                var v = Numbers();
                var e = v.GetEnumerator();

                int[] expected = { 11, 22, 33 };

                Numbers().Should().ContainInOrder(expected);

            }

        }
    }

现在请仔细注意这里发生的事情。我是NOT构建一个反应式可观察对象。我正在构建一个 IEnumerable。它严格来说是一个拉动系统。我可以很高兴地写。

    foreach item in Numbers(){
            Console.WriteLine(item);
    }

它会打印出来

    11
    22
    33

这非常有趣,因为系统并不是严格异步的,但我滥用了等待框架和“等待任何内容”的能力,如此处所述。http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx.The 问题) are.

  1. 这种对await/async 的滥用能走多远?
  2. 该模式与 F# 计算表达式一样强大吗
  3. 传统的 IEnumerator / Yield 模式只是评估的语法糖吗 正是按照这个模式

实现该模式的代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading.Tasks;

    namespace EnumerableViaAwait
    {

        public class EnumeratorMonad<T> : IEnumerable<T>, IEnumerator<T>
        {
            public class Yield
            {
                private EnumeratorMonad<T> _Monad;

                public Yield(EnumeratorMonad<T> monad)
                {
                    _Monad = monad;
                }

                public YieldAwaiter GetAwaiter()
                {
                    return new YieldAwaiter(_Monad);
                }
            }

            public class YieldAwaiter : INotifyCompletion
            {
                EnumeratorMonad<T> _Monad;

                public YieldAwaiter(EnumeratorMonad<T> monad)
                {
                    _Monad = monad;
                }

                public bool IsCompleted
                {
                    get { return _Monad.IsCompleted(); }
                }

                public void GetResult()
                { }

                public void OnCompleted(Action continuation)
                {
                    _Monad.Next = continuation; 
                }

            }

            private bool Completed { get; set; }

            public EnumeratorMonad()
            {
                Completed = false;
            }

            public bool IsCompleted()
            {
                return Completed;
            }

            public void Build(Func<Func<T, Yield>, Task> action)
            {
                Func<T, Yield> yielder = (T value) => { 
                    _Current = value;
                    return new Yield(this);
                };
                Next = async () => { 
                    await action(yielder);
                    Completed = true;
                };
            }

            private T _Current;
            public T Current
            {
                get { return _Current; }
            }

            public void Dispose()
            {
            }

            object System.Collections.IEnumerator.Current
            {
                get { return _Current; }
            }


            Action Next;
            public bool MoveNext()
            {
                if (!Completed )
                {
                    Next();
                }
                return !Completed;
            }

            public void Reset()
            {
                throw new NotImplementedException();
            }



            IEnumerator<T> IEnumerable<T>.GetEnumerator()
            {
                return this;
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return this;
            }
        }

        public class EnumeratorMonad{
            public static EnumeratorMonad<T> Build<T>(Func<Func<T, EnumeratorMonad<T>.Yield>, Task> action)
            {
                var monad = new EnumeratorMonad<T>();
                monad.Build(action);
                return monad;
            }
        }

}


yield return and await/async只是协程的不同专门形式。您已经证明您可以(本质上)实施yield return using await/async,如果发现反过来也是可能的,我不会感到惊讶。我确信它们是以非常相似的方式实现的。

当然,在实践中我不会使用await/async对于迭代,因为yield return更简单、更清晰。

So,

  1. 您可能可以随心所欲地接受这种“滥用”。
  2. 对 F# 不够熟悉,无法回答。
  3. 不,但 IIRC 的功能以或多或少相同的方式实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中 async/await 的这种用法以前被发现过吗? [关闭] 的相关文章

  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri

随机推荐

  • C# 应用程序退出时会自动释放托管资源吗?

    我完全知道 using 语句是处理的方式IDisposables 请不要在评论中重复此建议 当 C NET 4 5 或更高版本 应用程序关闭时 会发生什么IDisposable哪些没有得到妥善处置 我知道有些有一个用于处理非托管资源的终结器
  • 如何使用 Webkit 在 Ubuntu 11.04 (Natty Narwhal) 上运行 Eclipse SWT 浏览器组件?

    我在 Eclipse RCP 应用程序中使用 SWT 浏览器控件 在 Linux Ubuntu 10 10 上 这取决于安装 xulrunner 1 9 2 的用户 这很好用 然而 在 Ubuntu 11 04 上 我发现它默认随 xulr
  • 如何在两个不同的 Android 应用程序之间共享 SharedPreferences 文件?

    我已经为此苦苦挣扎了一段时间 基本上 我想让两个应用程序 总是安装在一起 共享首选项 其中一个只是在后台运行并需要使用首选项的服务 应该拥有首选项 但只really需要读取它们 另一个应用程序是前端 UI 应用程序 需要能够写入另一个应用程
  • 拖放图像输入文件并在上传前预览[重复]

    这个问题在这里已经有答案了 我想创建一个 div 附加拖放功能 当有人单击它时 他们可以选择他们的图像 我已经编码了一些东西并且它可以 单击 div 并选择您的图像 上传前预览图像 你可以检查我的小提琴 css uploader width
  • Ajax(这个)不工作

    当尝试访问 container 的 box 类时 在 ajax 调用内部使用 this 不起作用 container on click box function event var description if this 0 style w
  • NumPy 索引:使用布尔数组进行广播

    相关这个问题 我通过布尔数组和广播遇到了索引行为 我不明白 我们知道可以使用整数索引和广播对二维 NumPy 数组进行索引 这是在docs a np array 0 1 2 3 4 5 6 7 8 9 10 11 b1 np array F
  • 打字稿 |不可变 |扩展 Immutable.Map 类型的正确方法

    我有一个用打字稿编写的带有不可变包的react redux应用程序 我有一个来自 api 的数据 在存储中我将其打包到 Map 中 在所有应用程序中 它们都用作地图 我创建了一个界面 export interface PaymentMeth
  • iOS:让应用程序像服务一样运行

    在 iOS 中 我如何指示操作系统让我的应用程序保持运行 即使它不再位于前台 Skype Viber Empatica Zenly 还有更多的应用程序可以做到这一点 基本上 iOS 中不存在服务类型应用程序或功能之类的东西 即使是 后台 应
  • 从“int”转换为“size_t”可能会改变结果的符号 - GCC,C

    在我的项目中 我打开了将警告视为错误并使用 pedantic and ansi标签 我正在使用 GCC 编译器 在这个项目中 我必须使用第三方源代码 该源代码有很多警告 由于我将警告视为错误 因此我在修复他们的代码时遇到了困难 大多数警告都
  • 如何在 IE7 中垂直对齐文本而不使用 CSS 'table-cell' 属性?

    我有固定高度的 div 其中包含文本 我希望文本在 div 中间垂直对齐 但问题在于某些文本是单行 而有些文本则分成两行 对于 IE8 Chrome 和 Firefox 使用display table cell and vertical a
  • 在函数中创建类并访问在包含函数的作用域中定义的函数[重复]

    这个问题在这里已经有答案了 Edit 请参阅我在这个问题底部的完整答案 tl 博士回答 Python 具有静态嵌套作用域 这static方面可以与隐式变量声明交互 产生不明显的结果 这可能特别令人惊讶 因为该语言通常是动态的 我以为我对 P
  • Python:midi 到音频流

    我需要将 MIDI 数据转换 合成为音频流 PCM 数据 有什么简单的方法可以做到这一点 随你挑选关于你想要做什么 页面上有一个 MIDI 部分
  • 在matplotlib中计算白色背景上alpha为0.5的RGB等效值

    我希望能够在 matplotlib 中以 0 5 的 alpha 值在白色背景上复制原色 r g 或 b 的外观 同时将 alpha 值保持为 1 下面是一个示例 通过手动实验 我发现 alpha 为 1 的 RGB 值看起来与 alpha
  • 当没有返回结果时处理 ExecuteScalar()

    我正在使用以下 SQL 查询和ExecuteScalar 从Oracle数据库获取数据的方法 sql select username from usermst where userid 2 string getusername comman
  • 重置用户密码

    我正在尝试找到一种通过非交互式登录在 Azure Active Directory 中重置用户密码 所有用户 而不仅仅是经过身份验证的用户 的解决方案 目前看来这只能通过 powershell 的 MSOnline 获得Set AzureA
  • Android 模拟器替代品

    我对 Android 开发完全陌生 但我刚刚拥有一台 HTC Hero 想为其开发一些应用程序 然而 我使用笔记本电脑作为我的开发机器 并且模拟器非常慢 启动大约需要 10 15 分钟 虽然我可以让它保持打开状态 但在使用其他应用程序 如
  • LINQ 按空列排序,其中顺序为升序,空值应该在最后

    我正在尝试按价格对产品列表进行排序 结果集需要按列按价格从低到高列出产品LowestPrice 但是 该列可以为空 我可以按降序对列表进行排序 如下所示 var products from p in context Products whe
  • 如何从Application.Path获取UNC路径?

    我想获取 vba 代码中活动工作簿的路径 ActiveWorkbook Path做这个 BUT 我需要它来检索这样的东西 MachineName ShareFolder ETC ETC2 NOT S ETC ETC2 Where S 映射到
  • 为什么在访问模型时,backbone.js 返回一个空数组?

    我有一个路由器访问其集合 我的 for 循环没有迭代模型 因此我尝试记录集合以查看它返回的内容 事实证明 当我直接记录集合时 我会按预期看到所有模型 但是 如果我尝试记录集合的 models 属性 我会得到一个空数组 这没有道理 这些线直接
  • C# 中 async/await 的这种用法以前被发现过吗? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 在我之前在 stackoverflow 上提出了关于 async await 的问题之后