Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更改异步方法调用以防止强制异步向上调用堆栈_C#_Asp.net Mvc_Asynchronous_Task Parallel Library_Servicebus - Fatal编程技术网

C# 如何更改异步方法调用以防止强制异步向上调用堆栈

C# 如何更改异步方法调用以防止强制异步向上调用堆栈,c#,asp.net-mvc,asynchronous,task-parallel-library,servicebus,C#,Asp.net Mvc,Asynchronous,Task Parallel Library,Servicebus,如果我需要调用一个在内部调用某个异步方法的方法,作为一个fire-and-forget操作,我如何防止这个调用强制“async”需要在调用堆栈中使用,比如说…一个MVC控制器 例如:我的MVC控制器(非异步)调用一个业务层方法,该方法反过来调用Windows Azure服务总线QueueClient.SendAsync(BrokeredMessage)将消息放入队列,但无需等待消息完成 通常,当调用此控制器操作时,编译器将抛出一个错误,即此时无法启动异步操作 我知道,我可以使用ContinueW

如果我需要调用一个在内部调用某个异步方法的方法,作为一个fire-and-forget操作,我如何防止这个调用强制“async”需要在调用堆栈中使用,比如说…一个MVC控制器

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

通常,当调用此控制器操作时,编译器将抛出一个错误,即此时无法启动异步操作

我知道,我可以使用ContinueWith()来执行异步操作回调上的代码,而不是等待或只是调用SendAsync()方法,但我被告知这不是正确的解决方案。(见对报告的答复)


有人能告诉我解决这个问题的最佳方法吗?告诉我为什么ContinueWith()方法不正确?

MVC控制器方法处理HTTP请求并将相应的HTTP响应发送回客户端。如果我正确理解了您的问题,那么您希望从异步MVC控制器方法调用fire-and-forget方法,然后继续HTTP响应传递,这样fire-and-forget方法就不会保存响应

事实上,如果不等待其结果,您就无法使用控制器方法以这种方式从中激发它。也就是说,您可以,但是如果您的ASP.NET应用程序将重新启动,或者IIS服务器将从服务器场中取出,则将永远不会调用您的
ContinueWith
回调。因此,您不知道该请求是否已到达Windows Azure服务

解决这一问题的一种方法是在同一台主机上或同一网络上的另一台主机上运行helperwebapi或WCF服务(因此服务调用的周转非常快)。它可以是自托管服务。您可以从MVC控制器调用此帮助器服务,只需排队执行fire-and-forget操作。您将等待此调用的结果,但在本例中这不是问题,因为此操作的调用者和被调用者都将存在于同一网络上

这样,原始MVC HTTP响应就不会被搁置。在helper服务中,然后执行
等待QueueClient.SendAsync()
调用Windows Azure总线并相应地处理此操作的结果

调用Windows Azure服务总线QueueClient.SendAsync(BrokeredMessage),将消息丢弃到队列中,但无需等待消息完成

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

通常,当调用此控制器操作时,编译器将抛出一个错误,即此时无法启动异步操作

确保没有任何
异步void
方法或。如果Azure存储库导致该异常,我会非常惊讶

有人能告诉我解决这个问题的最佳方法吗?告诉我为什么ContinueWith()方法不正确

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



但是,如果100毫秒真的无法忍受,并且您愿意放弃可靠性(在这种情况下,这意味着您接受这样一个事实,即即使操作成功完成,但某些消息可能无法发送到总线,因此客户机认为它们已经发送了),然后,您可以使用来最大限度地减少消息丢失的机会。

我认为,旋转web API并将控制器调用从内部业务层更改为同一业务层的HTTP端点外观是过分的……我不愿意这样做。另外,我的控制器不是异步的。它简单地调用业务层DLL,而业务层DLL又利用了具有异步方法的Azure SB API。我不想将我的控制器更改为异步,或在控制器中进行异步操作。@ThiagoSilva,我当然不清楚您的控制器是否异步。如果我不够清楚,我深表歉意,但我感谢您的回答!我理解您在删除邮件时关于可靠性的第一点。此时,我可能不会将我的MVC控制器更改为async,也不会将操作更改为async方法,因为这假设我正在将业务层的接口更改为async方法(一直采用async)。如果我使用ContinueWith()但使用重载传入CancellationToken.None,TaskContinuationOptions.DenyChildataTach,TaskScheduler.Default,这是否应该考虑默认ContinueWith()重载的“危险性”并提供可靠性方面?指定所有参数将考虑“危险性”,但不会给你带来可靠性。您的建议与调用
Task.Run
基本相同。如果您不想将业务层(等)更改为异步,那么您应该只调用
Send
,而不是
sendsync