如何改变异步方法调用prevent强制异步调用堆栈 [英] How to change async method call to prevent forcing async up the call stack

查看:133
本文介绍了如何改变异步方法调用prevent强制异步调用堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我需要调用这反过来内部调用一些异步方法的方法,如火灾,忘记操作,我怎么能prevent从强迫异步需要此调用中使用调用堆栈说...一个MVC控制器?

例如:我的MVC控制器(未异步)调用业务层的方法,这反过来又调用Windows Azure的服务总线QueueClient.SendAsync(BrokeredMessage),在队列中删除消息,但并不需要等待它完成。

通常,当调用此控制器动作,编译器将抛出一个异步操作不能在这个时候启动一个错误。

我知道,而不是等待,或只是调用SendAsync()方法,我可以ContinueWith()跟进,以便在异步操作的回调执行code,但我已经告诉这不是一个正确的解决方案。 (参见对 MVC 4调用控制器异步方法)

会有人在意见识一下来解决这种情况的最好方法?并告诉我,为什么ContinueWith()方法是不正确的?


解决方案

  

调用Windows Azure的服务总线QueueClient.SendAsync(BrokeredMessage),在队列中删除消息,但并不需要等待它完成。


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


  

通常,当调用此控制器动作,编译器将抛出一个异步操作不能在这个时候启动一个错误。


确保您没有任何异步无效或方法的 EAP方法调用。如果Azure存储库会导致例外,我会感到非常惊讶。


  

会有人在意见识一下来解决这种情况的最好方法?并告诉我,为什么ContinueWith()方法是不正确的?


最好的解决方法就是拥抱异步 ContinueWith 可以工作,但使用起来危险(它有很多的参数,其中一些不安全的默认值); 等待实际上是一样的 ContinueWith ,但没有危险的默认值。


不过,如果100ms的是真正的难以忍受,你是愿意放弃的可靠性(在这种情况下,这意味着你接受这个事实,一些消息的可能不会被发送到总线的,即使行动成功完成,所以客户端的认为他们确实的),那么你可以使用的 BackgroundTaskManager 从我的博客以尽量减少消息丢失的几率。

If I need to call a method that in turn calls some async method internally, as a fire and forget operation, how can I prevent this call from forcing the "async" to need to be used up the call stack to say...an MVC controller?

For example: My MVC Controller (not async) calls a business layer method, which in turn 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.

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

I know that instead of awaiting or just invoking the SendAsync() method, I could follow it up with ContinueWith(), in order to execute code on the callback of the async operation, but I've been told this not a correct solution. (see responses to MVC 4 calling async method in controller)

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

解决方案

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.

First, I'd reconsider this assumption. If you want a fully reliable system, the action should wait for the message to be sent to the bus. Note that this is usually a fast operation (100ms).

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

Ensure that you do not have any async void methods or EAP method calls. I would be very surprised if the Azure storage library causes that exception.

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

The best solution is to embrace async. ContinueWith could work but is dangerous to use (it has lots of parameters, some of which have unsafe default values); await is practically the same as ContinueWith but without the dangerous defaults.


However, if 100ms is truly unbearable, and you are willing to give up reliability (in this case, that means you accept the fact that some messages may not get sent to the bus even though the action completed successfully so the client thinks that they did), then you can use the BackgroundTaskManager from my blog to minimize the chance of lost messages.

这篇关于如何改变异步方法调用prevent强制异步调用堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆