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 中的 char* 获取单个字符

    有没有办法在 C 中逐字符遍历或从 char 中提取单个字符 考虑以下代码 现在获得单个角色的最佳方式是什么 建议我一种不使用任何字符串函数的方法 char a STRING 其他方式 char i for i a i i i points
  • “字符串”是什么意思?信息'

    我刚刚在查看定义时发现了这个PlatformNotSupportedException class 什么是string message意思是 据我所知是 是缩写Nullable lt gt but Nullable lt gt 只能应用于结
  • is_integral 与 is_integer:其中之一是多余的吗?

    是积分 http en cppreference com w cpp types is integral and 是整数 http en cppreference com w cpp types numeric limits is inte
  • 可变数量的(常量)引用参数

    我试图从我的高级代码 使用 C 11 中消除原始指针 并且我找到了引用 尤其是const 在许多情况下 当没有所有权转移时 是一个很好的替代品 但如果有的话该怎么办variable我想通过 常量 引用传递的参数数量 你不能创建一个std v
  • 如何在asp.net中异步执行两个作业

    网 我需要你的帮助请帮助我 请参阅我的代码 如果我的第一份工作完成 则退出btn ok代码隐藏并更新到 ASP NET 屏幕 但同时作业 2 必须工作 正在处理批量电子邮件 protected void btn ok object send
  • 当 f & g 修改同一个全局变量时,表达式 f() > g() 的值是否未定义或未指定?

    UPDATE 由用户标记ecatmur 它是重复的在 C99 中 f g 是未定义还是只是未指定 https stackoverflow com questions 3951017 in c99 is fg undefined or mer
  • 将 void *user_data 转换为对象

    我该如何投射void something到标准 C 中的对象 具体来说我想投void userdata to std map
  • & 运算符的含义是什么?

    在下面的代码中 Expression
  • 为什么将 char 传递给函数会改变它在 c 中的值?

    我目前正在关注本作业簿 http www cs bham ac uk exr lectures opsys 10 11 lectures os dev pdf关于构建操作系统 我的目的是写一个64位内核 我已经在文本模式下加载 内核 代码并
  • 多维数组和指向指针的指针

    创建多维数组时char a 10 10 根据我的书 它说你必须使用类似于char a 10 将数组传递给函数 为什么必须这样指定长度 您不是只是将双指针传递给 with 并且该双指针不是已经指向分配的内存吗 那么为什么参数不能是char a
  • 以编程方式运行 T4 文本模板

    有没有一种方法可以通过代码以编程方式运行 T4 文本模板 我正在制作一种自定义域特定语言 我希望相关的文本模板在用户每次保存时运行 目前 这就是我在 DSL 模型中所做的事情 protected override void OnDocume
  • Identity Server 4:添加访问令牌的声明

    我正在使用 Identity Server 4 和隐式流 并且想要向访问令牌添加一些声明 新的声明或属性是 tenantId 和 langId 我已将 langId 添加为我的范围之一 如下所示 然后通过身份服务器请求 但我也获得了tena
  • 为什么 httpRuntime targetFramework="4.5" 禁止抓取 .ASPXAUTH cookie?

    当我的 web config 具有以下 httpRuntime 时 我的控制器无法获取 cookie ASPXAUTH 它似乎能够获取任何其他 cookie 无论带或不带句点前缀 如果我删除下面的行 它就可以正常工作
  • C 中的链表数组:初始化和插入?

    我需要创建一个链表数组 如图所示 这就是我到目前为止所做的 typedef struct Node int data struct Node next Node int main void Node link 5 for int q 0 q
  • 加载 angularjs 路由后运行 javascript 代码

    我需要在 angularjs 加载路线后显示警报 显示警报的代码位于 angularjs 异步加载的视图中 视图加载后 我希望它能够运行 但它没有 我知道我可以广播并告诉它稍后运行等 但我需要一个更通用的解决方案 假设您正在谈论基于以下内容
  • 从视图模型调用方法的命令

    好吧 我倾向于避免使用命令 因为它们总是让我感到困惑 但我正在进行一个新项目 并且正在尝试正确构建它 并且在我看来没有任何代码隐藏 基本上我现在想做的就是连接一个按钮来触发一个命令 在我的视图模型上执行一些操作 但不知何故 如此简单的事情仍
  • 替换全局热键

    我有一个位于托盘中的应用程序 我想定义多个热键来触发我的程序中的事件 我从 AaronLS 在这个问题中的出色回答中找到了灵感 使用C 设置全局热键 https stackoverflow com a 27309185 3064934 如果
  • 在 Map() 的条目上使用 Promise.all

    我正在使用 Map 来表示一些键 值对 let myMap new Map myMap set foo bar myMap set foo2 bar42 对于每个 Map 条目 我执行一个返回 Promise 的函数 所有这些 Promis
  • DataGridView 捕获用户行选择

    我在处理选择时遇到问题DataGridView 我的网格视图包含一个金额列 表单上有一个文本框 应显示所选网格视图行的总数 因此 我需要在用户选择 取消选择 gridview 行时捕获事件并相应地计算 添加 减去 金额 我找到了两种方法 使
  • C#:如何处理乱序 TCP 数据包?

    请有人解释一下如何处理乱序数据包 我使用原始套接字来捕获数据包 并在数据包到来时解析它们 但其中一些数据包的顺序错误 例如 ID 标志 16390 PSH ACK 16535 PSH ACK 16638 确认 16640 PSH ACK 1

随机推荐

  • 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 的问题之后