其他分享
首页 > 其他分享> > CodeGo.net>如何更改异步方法调用,以防止强制向上调用堆栈

CodeGo.net>如何更改异步方法调用,以防止强制向上调用堆栈

作者:互联网

如果我需要调用一个方法,该方法又在内部调用了一些异步方法,这是一种即发即弃的操作,那么如何防止此调用迫使“异步”需要用完调用堆栈才能说… MVC控制器?

例如:我的MVC控制器(非异步)调用业务层方法,该方法又调用Windows Azure服务总线QueueClient.SendAsync(BrokeredMessage),以将消息放入队列中,但无需等待它就可以完成.

通常,当调用此控制器操作时,编译器将引发错误,表明此时无法启动异步操作.

我知道,除了等待或仅调用SendAsync()方法外,我还可以继续使用ContinueWith()以便在异步操作的回调上执行代码,但是有人告诉我这不是一个正确的解决方案. (请参阅对Calling async method in controller的答复)

有人愿意启发我解决此问题的最佳方法吗?并告诉我为什么ContinueWith()方法不正确?

解决方法:

calls the Windows Azure Service Bus QueueClient.SendAsync(BrokeredMessage), to drop a message in a queue, but doesn’t need to wait for it to complete.

首先,我将重新考虑这个假设.如果您想要一个完全可靠的系统,则该操作应等待消息发送到总线.请注意,这通常是一个快速操作(100毫秒).

Typically, when this controller action is invoked, the compiler will throw an error that the async operation cannot be started at this time.

确保您没有任何异步void方法或EAP method calls.如果Azure存储库导致该异常,我将感到非常惊讶.

Would someone care to enlighten me on the best way to fix this scenario? And tell me why the ContinueWith() approach is not correct?

最好的解决方案是拥抱异步. ContinueWith可以工作,但使用起来很危险(它有很多参数,其中一些参数具有不安全的默认值); await实际上与ContinueWith相同,但是没有危险的默认值.

但是,如果100ms确实难以忍受,并且您愿意放弃可靠性(在这种情况下,这意味着您接受以下事实:即使操作成功完成,某些消息也可能不会发送到总线,因此客户端认为它们确实),那么您可以使用BackgroundTaskManager from my blog将邮件丢失的可能性降到最低.

标签:servicebus,task-parallel-library,asynchronous,c,asp-net-mvc
来源: https://codeday.me/bug/20191029/1962084.html