C# WebAPI有条件异步返回响应

C# WebAPI有条件异步返回响应,c#,asynchronous,asp.net-web-api,async-await,C#,Asynchronous,Asp.net Web Api,Async Await,我有一个上传功能,它获取一个图像并将图像大小调整为不同的大小,然后将100x100图像的路径返回给用户。 在我的例子中,用户将等待所有大小调整和上传完成,这显然不利于用户体验。 我尝试将ActionResult作为异步任务,但在执行时遇到了问题。 这是我现在的代码,等待所有上传完成 [HttpPost] [Route("UploadProfileImage")] public async Task<IHttpActionResult> UploadProfileIm

我有一个上传功能,它获取一个图像并将图像大小调整为不同的大小,然后将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);
        }
[HttpPost]
[路由(“上传档案图像”)]
公共异步任务UploadProfileImage()
{
字符串userId=Identifier.GetIdentifier();
ReturnResult响应=新的ReturnResult();
尝试
{
var provider=新的MultipartMemoryStreamProvider();
wait Request.Content.ReadAsMultipartAsync(提供程序);
var fileNameParam=provider.Contents[0]。Headers.ContentDisposition.Parameters.FirstOrDefault(p=>p.Name.ToLower()==“filename”);
字符串文件名=(fileNameParam==null)?“”:fileNameParam.Value.Trim(“”);
字节[]文件=等待提供程序。内容[0]。ReadAsByteArrayAsync();
MemoryStream imgStream=新的MemoryStream(文件);
位图mg=新位图(imgStream);
列表大小=新列表();
添加(新尺寸{Width=mg.Width,Height=mg.Height});
添加(新尺寸{宽度=100,高度=100});
添加(新尺寸{宽度=300,高度=300});
添加(新尺寸{宽度=500,高度=500});
添加(新尺寸{宽度=800,高度=800});
int指数=0;
foreach(变量大小,以大小为单位)
{
byte[]newImageByteArray=Helpers.CreateImageThumbnail(文件,Convert.ToInt32(size.Width),Convert.ToInt32(size.Height));
SaveProfileImage(newImageByteArray,agentId,size,index==0?true:false);
索引++;
//---*--->>在这里我应该检查一下,如果上传了原始和100x100图像,那么返回一个响应并继续上传其他图像(如果(索引>1))
}
var path=“/users/uploads/100/”+userId+”.jpg“+”?v=“+Guid.NewGuid();
UpdateUploadImage(用户ID,路径);
response.ReturnObject=路径;
response.ReturnCode=ReturnCodes.Success;
返回Ok(响应);
}
捕获(例外情况除外)
{
response.ReturnObject=ex;
response.ReturnCode=ReturnCodes.Exception;
返回Ok(响应);
}
注意:客户端是发布到webapi服务器的angularJS应用程序。 你知道如何重写代码来达到这个目的吗

我尝试将ActionResult作为异步任务,但在执行时遇到了问题

这不是正确的解决方案,因为(正如我在博客上所描述的)。它不可能是正确的解决方案,因为:

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

web请求如何向用户返回响应,然后再返回(以返回路径)?对于HTTP这样的请求/响应协议,这是不可能的;每个请求只能得到一个响应

在我的例子中,用户将等待所有大小调整和上传完成,这显然不利于用户体验

你的选择是:

  • 加入一个复杂的解决方案,跟踪独立于HTTP请求的工作(这通常需要一个可靠的队列,如Azure队列,连接到一个独立的辅助服务,如Azure函数),然后提供一些方法主动通知UI完成(SignalR在这方面很好,除非您需要非常大的规模,在这种情况下,轮询可能会更好)
  • 在客户端使用AJAX
  • 请注意,您已经在执行(2):

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

    因此,您所要做的就是更改客户端,使其不必等待请求,然后再允许用户执行其他操作。无需更改服务器

    我尝试将ActionResult作为异步任务,但在执行时遇到了问题

    这不是正确的解决方案,因为(正如我在博客上所描述的)。它不可能是正确的解决方案,因为:

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

    web请求如何向用户返回响应,然后再返回(以返回路径)?对于HTTP这样的请求/响应协议,这是不可能的;每个请求只能得到一个响应

    在我的例子中,用户将等待所有大小调整和上传完成,这显然不利于用户体验

    你的选择是:

  • 加入一个复杂的解决方案,跟踪独立于HTTP请求的工作(这通常需要一个可靠的队列,如Azure队列,连接到一个独立的辅助服务,如Azure函数),然后提供一些方法主动通知UI完成(SignalR在这方面很好,除非您需要非常大的规模,在这种情况下,轮询可能会更好)
  • 在客户端使用AJAX
  • 请注意,您已经在执行(2):

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


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

    旁注:我怀疑您的“用户”“客户端端应用程序在这种情况下,将服务器端代码从同步更改为异步会对客户端代码行为产生零影响,因为服务器调用是异步的。请考虑如果您应该发布,以澄清用户是ANGLARJS APPI的。因此,没有单独的重写服务器端代码可以解决您的问题。(通过并行一些工作可以减少等待时间,但不会完全删除它)。我明白了。但是,例如