异步任务适用于HttpClient对象,但不适用于Web通用处理程序中的项目类

萤火虫

我发现.NET Framework的HttpClient类/对象与VS-2013 Project PhotoServer(DLL)类/对象之间存在有趣的区别。这让我想知道脚本是否存在错误。

我正在使用.NET Framework v4.5.1。

我在同步Web通用处理程序中使用HttpClient脚本。注意,我正在使用“ .Result”进行异步POST以等待响应。因此,查看有效的HttpClient是

 using (var httpClient = new HttpClient())
 {
     var response = httpClient.PostAsync(
         _baseUrl,
         new FormUrlEncodedContent
         (
             new List<KeyValuePair<string, string>>
             {
                 new KeyValuePair<string, string>("Vin", parmVin), 
                 new KeyValuePair<string, string>("ImageSize", parmImageSize)
             }.ToArray()
         )
     ).Result;

     //returned string[] datatype...
     var photoUrls = response.Content.ReadAsStringAsync().Result;
 }

我正在同步Web通用处理程序中使用“ GetPhotoUrlsAsync”脚本。此“ GetPhotoUrlsAsync”对象来自Project类(DLL)。同样,我使用的是“ .Result”,它不起作用,只是死锁并挂起。我想知道为什么会这样,并且脚本中有错误吗?

 //[Scripts in Web Generic Handlers]...
 var managerVehiclePhoto = new ManagerVehiclePhoto();
 var photoUrls = managerVehiclePhoto.GetPhotoUrlsAsync("12345678901234567").Result;

 //[Project Class]...
 namespace BIO.Dealer.Integration.PhotoServer
 {
      public seal class VehiclePhotoManager
      {
          public async Task<string[]> GetPhotoUrlsAsync(string vin)
          {
              var listResponse = await _client.ListAsync(vin);
              return listResponse.ToArray();
          }
      }
 }

谢谢...

编辑#1

    //Synchronous API Call...

    public string[] GetPhotoUrls(string vin)
    {
        return GetPhotoUrlsAsync(vin).Result;
    }
斯蒂芬·克莱里

.Result在这两种情况下,这样使用实际上是一个错误。它只是在这种HttpClient情况下不会死锁请注意,如果像这样使用HttpClient,则其他平台(尤其是Windows Phone,IIRC)上的相同死锁。

我在博客上详细描述了僵局,但是要点是:

每次使用时,默认情况下都会捕获一个ASP.NET“请求上下文” await当该async方法恢复时,它将在该上下文中恢复。但是,诸如此类HttpContext不是多线程安全的,因此ASP.NET一次只能将该上下文限制为一个线程。因此,如果您通过调用.Result来阻塞线程,那么它将阻塞该上下文中的线程。

GetPhotoUrlsAsync死锁的原因是因为它是一个async试图在该上下文中恢复方法,但是在该上下文中已经有一个线程被阻塞。之所以HttpClient起作用,是因为GetAsync等实际上不是async方法(请注意,这是一个实现细节,您不应依赖此行为)。

解决这个问题的最好办法是更换.Resultawait

var managerVehiclePhoto = new ManagerVehiclePhoto();
var photoUrls = await managerVehiclePhoto.GetPhotoUrlsAsync("12345678901234567");

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

多态参数适用于超类,但不适用于子类

CSS类适用于表内部,但不适用于表本身

已发布作品适用于单个对象,但不适用于对象数组

日志记录适用于多处理,但不适用于loky

AWS Cognito身份验证适用于Postman,但不适用于Angular Web应用程序

ScalaJs + ZIO:程序适用于sbt 1.2.8,但不适用于> = 1.3

ssh私钥适用于root用户,但不适用于普通用户

服务参考适用于Windows窗体,但不适用于类库

预处理语句适用于INSERT,但不适用于SELECT

由ASP.NET通用处理程序(.ashx)生成的动态图像文件不适用于JavaScript

Facebook Web应用程序登录仅适用于IP,但不适用于域

通用排序适用于整数,但不适用于其他类型

jQuery验证适用于类,但不适用于规则和消息

通用应用程序NTLM适用于Windows应用商店,但不适用于Windows Phone

优先队列适用于引导程序,但不适用于列表

Angular指令适用于内联样式,但不适用于类

API适用于Java应用程序,但不适用于JavaFX

Symfony 项目适用于实时服务器,但不适用于 wamp

通用证书适用于生产但不适用于开发

notifydatasetchanged 不适用于异步任务

程序适用于 Ubuntu 17.04 和 17.10,但不适用于 Ubuntu 18.04

Angular Test 仅适用于模拟服务类,但不适用于值

单击时的 jQuery 类适用于桌面,但不适用于移动设备

适用于 PHP 但不适用于脚本

应用程序适用于 iphone 11 但不适用于 iphone 8

IIS Windows 身份验证适用于网站,但不适用于网站下的 Web 应用程序

从 localStorage 检索对象适用于控制台日志,但不适用于页面

我的 recyclerView 适用于调试,但不适用于“运行应用程序”

Django 项目适用于本地但不适用于 heroku