加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 包括异步签名(没有在主体中等待)对程序流有什么影响?

发布时间:2020-12-15 23:36:53 所属栏目:百科 来源:网络整理
导读:一般问题 我刚刚在一个方法的签名中找到了一个奇怪的行为,因为缺少一个异步修饰符.有了它,我得到了预期的行为,但没有它,我的程序表现得很奇怪. 问题是,方法的主体是完全同步的:没有一个等待在视线中.我甚至(如预期的那样)获得编译器警告1998: This async m
一般问题

我刚刚在一个方法的签名中找到了一个奇怪的行为,因为缺少一个异步修饰符.有了它,我得到了预期的行为,但没有它,我的程序表现得很奇怪.

问题是,方法的主体是完全同步的:没有一个等待在视线中.我甚至(如预期的那样)获得编译器警告1998:

This async method lacks ‘await’ operators and will run synchronously. Consider using the ‘await’ operator to await non-blocking API calls,or ‘await Task.Run(…)’ to do CPU-bound work on a background thread.

那么诱惑就是将其删除. (我的意思是,编译器基本上告诉我!)当我删除它时,我开始可靠地获得意外行为.

我的问题是:当没有等待时,异步真的在做什么?

背景/细节

我不认为我的应用程序的细节与我渴望理解的基本解释有关,但我会在这里加入它以给出一些风味……

我正在开发的程序消耗来自服务总线的消息.我方法的签名是:

public async Task<BrokeredMessage> ProcessMessageAsync(BrokeredMessage inMessage)

历史背景:我最初是从同事编写的类似程序中借用的,方法名称(暗示异步操作)是接口实现的一部分.

我删除异步修饰符时遇到的奇怪行为是该方法的主体被执行,但该消息以无法传递的形式返回.这样做的一个有趣结果是我最终会为每次重试尝试处理消息. (我很幸运,这是一个很低的数字!)

更新

正如Skeet先生所指出的那样,重要的是,尽管签名承诺返回Task类型的值,但我的方法实际上返回null.

解决方法

My question is: what is async really doing when there isn’t an await?

在可观察的行为方面:

>正如警告所说,代码仍将同步运行
>结果(包括抛出的任何异常)将包含在Task中

在实现方面,编译器将生成一个状态机来处理所有的异步.但这不应该改变任何其他行为.

我不能立即想到你会看到这种消息行为的任何原因,除非由于处理异常而产生差异.如果调用代码正在捕获异常但忽略了错误的任务(反之亦然),这肯定可以解释差异.我的第一个诊断步骤是添加一些日志记录,以查看该方法是否成功完成或是否在某处抛出异常.

现在你已经声明你返回null,这与调用者的观点有明显不同:返回Task< BrokeredMessage>的null值的方法和返回Task< BrokeredMessage>的方法之间存在巨大差异.其Result属性的值为null.调用者可能正在取消引用返回的值,并且抛出了NullReferenceException?

如果是这种情况,你的第一个调用端口应该是找出你以前无法看到该异常的原因 – 它表明缺少一些日志记录.然后你可以通过更改它来修复它:

return null;

return Task.FromResult<BrokeredMesage>(null);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读