WebAPI有条件地返回响应和异步

时间:2016-09-02 23:10:58

标签: c# asynchronous asp.net-web-api async-await

我有某种上传功能,可以拍摄图像并将图像调整为不同大小,然后将100x100图像的路径返回给用户。 在我的情况下,用户将等到所有调整大小和上传完成,这显然不利于用户体验。 我试图将我的ActionResult作为异步任务,但我很难做到这一点。 这是我现在的代码,等待所有上传完成。

 [HttpPost]
    [Route("UploadProfileImage")]
    public async Task<IHttpActionResult> UploadProfileImage()
    {
        string userId= Identifier.GetIdentifier();
        ReturnResult response = new ReturnResult();
        try
        {

            var provider = new MultipartMemoryStreamProvider();
            await Request.Content.ReadAsMultipartAsync(provider);
            var fileNameParam = provider.Contents[0].Headers.ContentDisposition.Parameters.FirstOrDefault(p => p.Name.ToLower() == "filename");
            string fileName = (fileNameParam == null) ? "" : fileNameParam.Value.Trim('"');
            byte[] file = await provider.Contents[0].ReadAsByteArrayAsync();
            MemoryStream imgStream = new MemoryStream(file);
            Bitmap mg = new Bitmap(imgStream);
            List<Size> sizes = new List<Size>();
            sizes.Add(new Size { Width = mg.Width, Height = mg.Height });
            sizes.Add(new Size { Width = 100, Height = 100 });
            sizes.Add(new Size { Width = 300, Height = 300 });
            sizes.Add(new Size { Width = 500, Height = 500 });
            sizes.Add(new Size { Width = 800, Height = 800 });
            int index = 0;
            foreach (var size in sizes)
            {

                byte[] newImageByteArray = Helpers.CreateImageThumbnail(file, Convert.ToInt32(size.Width), Convert.ToInt32(size.Height));
                Helpers.SaveProfileImage(newImageByteArray, agentId, size, index == 0 ? true : false);
                index++;
               //---*--->>Here I Should check here that if original & 100x100 image were uploaded then return a response and continue uploading the others (if(index>1))
            }
            var path = "/users/uploads/100/" + userId+ ".jpg" + "?v=" + Guid.NewGuid();


            UserManager.UpdateUploadImage(userId, path);
            response.ReturnObject = path;
            response.ReturnCode = ReturnCodes.Success;
            return Ok(response);
        }
        catch (Exception ex)
        {
            response.ReturnObject = ex;
            response.ReturnCode = ReturnCodes.Exception;
            return Ok(response);
        }

注意:客户端是发布到webapi服务器的angularJS应用程序。 知道如何重写代码才能实现这个目标吗?

1 个答案:

答案 0 :(得分:3)

  

我尝试将我的ActionResult作为异步任务,但我很难做到。

这不是正确的解决方案,因为async doesn't change the HTTP protocol(正如我在博客中描述的那样)。由于这个原因,它不是正确的解决方案:

  然后

将100x100图像的路径返回给用户。

Web请求如何向用户返回响应,然后再返回 (返回路径)?使用像HTTP这样的请求/响应协议是不可能的。每个请求只能得到一个回复​​。

  

在我的情况下,用户将等到所有调整大小和上传完成后,这显然不利于用户体验。

您的选择是:

  1. 提供一个独立于HTTP请求跟踪工作的复杂解决方案(这通常需要一个可靠的队列,如连接到像Azure功能这样的独立工作服务的Azure队列),然后提供一些主动通知UI的方法完成(SignalR对此有好处,除非你需要扩大规模,在这种情况下,轮询实际上可能更好)。
  2. 在客户端使用AJAX。
  3. 请注意,您已经在做(2):

      

    客户端是发布到webapi服务器的angularJS应用程序。

    因此,您所要做的就是更改客户端,以便在允许用户执行其他操作之前不会等待请求。无需更改服务器。