ASP中的异步Web服务。NET MVC

Alex Art。

我正在编写一个ASP.NET MVC 5应用程序,其中的其他应用程序使用Web服务来获取/处理一些数据。

该应用程序的数据流如下:MVC操作->服务B-> ExtSvc,它是Web服务的异步包装器

这里有些例子:

public class ExtSvc
{       
//Convert Event based async pattern to task based async pattern:

        private Task<Response> ProcessExtRequestAsync(Request request)
        {
            TaskCompletionSource<Response> taskCompletionSource =
                AsyncServiceClientHelpers.CreateSource<Response>(request);
            ProcessRequestCompletedEventHandler handler = null;
            handler =
                (sender, e) =>
                AsyncServiceClientHelpers.TransferCompletion(
                    taskCompletionSource, 
                    e, 
                    () => e.Result, 
                    () => this.Service.ProcessRequestCompleted -= handler);
            this.Service.ProcessRequestCompleted += handler;
            try
            {
              this.Service.ProcessRequestAsync(request, taskCompletionSource);
            }
            catch (Exception)
            {
                this.Service.ProcessRequestCompleted -= handler;
                taskCompletionSource.TrySetCanceled();
                throw;
            }

                return taskCompletionSource.Task;
            }

            //Usage:

            public async Task<Response> UpdateRequest(some arguments)
            {
                //Validate arguments and create a Request object

            var response = await this.ProcessExtRequestAsync(request)
            .ConfigureAwait(false);

            return response;
        }
}

B类是一种以同步方式使用ExtSvc的类

public class B
{
    public ExtSvc service {get; set;}

    public Response Update(arguments)
    {
       //some logic
       var result = this.ExtSvc.UpdateRequest(arguments).Result;
       //some logic
       return result 
    }
}

最后是MVC动作(也是同步的

public ActionResult GetResponse(int id)
{
     //some logic
     B.Update(id);
     //some logic
     return View(...);
}

所描述的流程抛出错误

System.Web.dll中发生类型为'System.InvalidOperationException'的第一次机会异常

附加信息:目前无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保将该页面标记为<%@ Page Async =“ true”%>。此异常也可能表示尝试调用“异步无效”方法,ASP.NET请求处理通常不支持该方法。相反,异步方法应返回一个Task,而调用者应等待它。

在ExtSvc的以下行上:this.Service.ProcessRequestAsync(request, taskCompletionSource); ProcessRequestAsync是一个void方法,因此它对应于:

此异常也可能表示尝试调用“异步无效”方法,ASP.NET请求处理通常不支持此方法。

我知道将GetResponse MVC操作转换为异步(通过使用async / await),并将实际使用ExtSvc的B类转换为异步也可以解决此问题。

但是我的问题是:

如果我不能更改B类的签名(由于它实现的接口)Task<Response>而不是返回Response则基本上意味着我不能对其使用async / await,那么如何解决此问题?

斯蒂芬·克莱里

ProcessRequestAsync是,void但不是async void看起来它是EBAP APIEBAP组件通常使用AsyncOperationManager/AsyncOperation,而反过来,它们确实用于SynchronizationContext将异步操作通知底层平台(最后一个链接是到我的MSDN文章SynchronizationContext)。

您看到的异常是因为ASP.NET看到(异步操作开始的)通知,并说:“哇,伙计。您是一个同步处理程序!您没有异步!”

放手,最好的方法是使所有应该异步的方法异步。这意味着B.Update应该B.UpdateAsync确定,所以有一个界面IB.Update-只需将界面IB.UpdateAsync更改为即可然后,您将一直处于异步状态,并且代码很干净。

否则,您将不得不考虑黑客。您可以Task.Run按照@neleus的建议使用-这是避免ASP.NET的一种方式,SynchronizationContext因此它不会“看到”异步操作的开始-但请注意,“环境上下文”(例如HttpContext.Current页面文化)会丢失。或者,您可以(临时)将a安装new SynchronizationContext()到请求线程上-这也避免了ASP.NETSynchronizationContext停留在同一线程上-但某些ASP.NET调用假定存在ASP.NETSynchronizationContext并将失败。

您可以尝试另一种方法。它可能有效,但我从未做到过。只需使您的处理程序返回aTask<ActionResult>并用于Task.FromResult返回视图:return Task.FromResult<ActionResult>(View(...));此hack将告诉ASP.NET您的处理程序是异步的(即使不是异步的)。

当然,所有这些黑客有主要缺点是你在做同步过异步(this.ExtSvc.UpdateRequest(arguments).Result),您将使用一个额外的不必要的线程为每个请求(或期间该装置2线,如果使用Task.Runhack)。因此,您将首先失去使用异步处理程序的所有好处-即可伸缩性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ASP中的异步Web服务。NET MVC

来自分类Dev

ASP .NET MVC 5中的异步任务

来自分类Dev

ASP.NET MVC中的异步方法

来自分类Dev

ASP .NET MVC Web服务和PostRepository

来自分类Dev

异步方法在ASP.NET(MVC)中在哪里执行?

来自分类Dev

在ASP.NET MVC中触发并忘记异步方法

来自分类Dev

异步方法在ASP.NET(MVC)中在哪里执行?

来自分类Dev

ASP.NET MVC在Controller中异步实现的最佳方法

来自分类Dev

使用asp.net mvc 中的web api 从服务Angular 6 调用REST 的POST 方法

来自分类Dev

如何从ASP.NET MVC项目引用Web服务?

来自分类Dev

Asp.net MVC调用登录Web服务

来自分类Dev

.Net MVC 使用 Web 服务

来自分类Dev

在ASP.Net MVC中使用异步

来自分类Dev

在 ASP.Net-MVC 中使用异步

来自分类Dev

要在服务器中添加哪些功能来部署ASP.Net MVC Web应用程序?

来自分类Dev

ASP MVC上的异步

来自分类Dev

在ASP.NET MVC Web Api中返回Json

来自分类Dev

ASP.NET 5 MVC 6中的web.config

来自分类Dev

在Android中访问Asp.net MVC Web Api

来自分类Dev

在ASP.NET MVC中锁定用户之间的Web对象

来自分类Dev

Web模型在ASP.NET MVC中不包含定义

来自分类Dev

Asp.net MVC web.config 中的客户错误

来自分类Dev

异步方法中的Mvc .Net Catch异常

来自分类Dev

在 foreach .net 4.5 mvc 中实现异步

来自分类Dev

在ASP.NET MVC Web API服务和MVC客户端体系结构中实现身份验证和基于角色的授权

来自分类Dev

Asp.Net Mvc服务层

来自分类Dev

使用Ajax在ASP.NET MVC中异步对GridView进行排序

来自分类Dev

在ASP.NET MVC5中调用异步方法时无法等待'long'

来自分类Dev

异步和等待在 asp.net MVC 中不起作用