2014-09-30 23 views
-2

無法找出這一個。思考?Web API--在異步操作仍在執行時完成的異步模塊或處理程序

[控制器]

await _imageRepo.Resize(name, width, height, queryParams, (image) => 
{ 
    response = createResponse(image); 
}); 

[倉庫]

public async Task Resize(string name, string width, string height, ImageOptions options, Action<Images> callback) 
{ 
    var actionName = "resized"; 
    var newWidth = Convert.ToInt32(width); 
    var newHeight = string.IsNullOrEmpty(height) ? newWidth : Convert.ToInt32(height); 
    var resizedName = ApplyOptionName(string.Format("{0}-{3}-{1}x{2}", name, newWidth, newHeight, actionName), options); 

    await Get(resizedName, null, async (previousImage) => 
    { 
     if (previousImage != null) 
     { 
      callback(previousImage); 
      return; 
     } 

     await Get(name, null, image => 
     { 
      if (image == null) 
      { 
       callback(null); 
       return; 
      } 

      using (ImageFactory imageFactory = new ImageFactory()) 
      { 
       imageFactory.Load(image.ToStream()); 

       imageFactory.Resize(new ResizeLayer(new Size(newWidth, newHeight), ResizeMode.Max, AnchorPosition.Left)); 

       ProcessImageOptions(imageFactory, options); 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        imageFactory.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 

        var newImage = Create(new Images(ms) { Name = resizedName }); 

        callback(newImage); 
       } 
      } 

     }); 

    }); 

} 

[異常]

[InvalidOperationException: An asynchronous module or handler completed while an asynchronous operation was still pending.] 

所有這些回調並不在我肚子裏坐好,但爲什麼我收到這個錯誤?

+0

我會讓你的repo返回圖像,然後構造響應。 (擺脫回調參數) – 2014-09-30 14:21:00

+0

我懷疑'Get'的回調是一個'Action',它會迫使'async' lambda成爲'async void',導致這個問題。最好的解決方案是完全擺脫IMO的回調,但你也可以把它們改成'Func <..., Task>'並且'等待'它們。 – 2014-09-30 14:34:22

回答

0

雖然回調不是很好。我們決定繼續使用這種模式。這意味着要弄清楚如何製作這些lambda的返回任務。

這很簡單。

Stephen Cleary寫道:「將它們更改爲Func < ...,任務> ...」。

所以這裏是最後的實現。

public async Task Resize(string name, string width, string height, ImageOptions options, Func<Images, Task> callback) 
{ 
    var actionName = "resized"; 
    var newWidth = Convert.ToInt32(width); 
    var newHeight = string.IsNullOrEmpty(height) ? newWidth : Convert.ToInt32(height); 
    var resizedName = ApplyOptionName(string.Format("{0}-{3}-{1}x{2}", name, newWidth, newHeight, actionName), options); 

    await Get(resizedName, null, async (previousImage) => 
    { 
     Images resizedImage = null; 

     if (previousImage != null) 
     { 
      resizedImage = previousImage; 
     } 
     else 
     { 
      await Get(name, null, async (image) => 
      { 
       if (image == null) 
       { 
        resizedImage = null; 
        return; 
       } 

       using (ImageFactory imageFactory = new ImageFactory()) 
       { 
        imageFactory.Load(image.ToStream()); 

        imageFactory.Resize(new ResizeLayer(new Size(newWidth, newHeight), ResizeMode.Max, AnchorPosition.Left)); 

        ProcessImageOptions(imageFactory, options); 

        using (MemoryStream ms = new MemoryStream()) 
        { 
         imageFactory.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 

         resizedImage = await CreateAsync(new Images(ms) { Name = resizedName }); 
        } 
       } 

      }); 
     } 

     await callback(resizedImage); 

    }); 

} 

一個較小的重新因素......但沒有造成傷害。

感謝您的幫助!

相關問題