c# – 包括异步签名(没有在主体中等待)对程序流有什么影响?
一般问题
我刚刚在一个方法的签名中找到了一个奇怪的行为,因为缺少一个异步修饰符.有了它,我得到了预期的行为,但没有它,我的程序表现得很奇怪. 问题是,方法的主体是完全同步的:没有一个等待在视线中.我甚至(如预期的那样)获得编译器警告1998:
那么诱惑就是将其删除. (我的意思是,编译器基本上告诉我!)当我删除它时,我开始可靠地获得意外行为. 我的问题是:当没有等待时,异步真的在做什么? 背景/细节 我不认为我的应用程序的细节与我渴望理解的基本解释有关,但我会在这里加入它以给出一些风味…… 我正在开发的程序消耗来自服务总线的消息.我方法的签名是: public async Task<BrokeredMessage> ProcessMessageAsync(BrokeredMessage inMessage) 历史背景:我最初是从同事编写的类似程序中借用的,方法名称(暗示异步操作)是接口实现的一部分. 我删除异步修饰符时遇到的奇怪行为是该方法的主体被执行,但该消息以无法传递的形式返回.这样做的一个有趣结果是我最终会为每次重试尝试处理消息. (我很幸运,这是一个很低的数字!) 更新 正如Skeet先生所指出的那样,重要的是,尽管签名承诺返回Task类型的值,但我的方法实际上返回null. 解决方法
在可观察的行为方面: >正如警告所说,代码仍将同步运行 在实现方面,编译器将生成一个状态机来处理所有的异步.但这不应该改变任何其他行为. 我不能立即想到你会看到这种消息行为的任何原因,除非由于处理异常而产生差异.如果调用代码正在捕获异常但忽略了错误的任务(反之亦然),这肯定可以解释差异.我的第一个诊断步骤是添加一些日志记录,以查看该方法是否成功完成或是否在某处抛出异常. 现在你已经声明你返回null,这与调用者的观点有明显不同:返回Task< BrokeredMessage>的null值的方法和返回Task< BrokeredMessage>的方法之间存在巨大差异.其Result属性的值为null.调用者可能正在取消引用返回的值,并且抛出了NullReferenceException? 如果是这种情况,你的第一个调用端口应该是找出你以前无法看到该异常的原因 – 它表明缺少一些日志记录.然后你可以通过更改它来修复它: return null; 至 return Task.FromResult<BrokeredMesage>(null); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |