2017-04-05 53 views
0

以下是運行.NET Framework的ASP.NET Core API。這是我的MVC控制器之一。將緩衝區寫入響應流或長時間運行請求結束?

我必須從外部服務獲取數據,只讓我一次獲得相當小的數據緩衝區 - 我無法控制這一點。比方說,我得到500行每緩衝區中的數據,但我的客戶希望一下子就被格式化爲CSV數據的,所以我要循環,並呼籲外部源,像這樣:

[HttpGet] 
public async Task<IActionResult> Get(MyRequest request) 
{ 
    var aggregateResponse = await client.GetDataAsync(request); 
    while (aggregateResponse.HasMoreData) 
    { 
     request.Cookie = aggregateResponse.Cookie; 
     var response = await client.GetDataAsync(request); 
     //Data is a list of objects containing n number of properties 
     aggregateResponse.Data.Concat(response.Data) 

     //I need the cookie from the previous response to get the next buffer 
     aggregateResponse.Cookie = response.Cookie; 
     aggregateResponse.HasMoreData = response.HasMoreData; 
    } 
    //runs through a generic IEnumerable CSV output formatter (uses reflection) 
    return Ok(aggregateResponse.Data); 
} 

可悲的是這可以花100-200個循環找回所有數據(aggregateResponse.Data中的50,000 - 100,000個列表項),但我沒有太多的選擇。

  • 難道是更有效的數據的每一個緩衝區格式化爲CSV在循環,並將其寫入到響應每次流,或者最好等到最終像我現在在做什麼?例如:

    [HttpGet] 
    public async Task<IActionResult> Get(MyRequest request) 
    
    { 
        var response = await client.GetDataAsync(request); 
        await Response.WriteAsync(formatBeginningData(response.Data)) 
        while (request.HasMoreData) 
        { 
         request.Cookie = aggregateResponse.Cookie; 
         response = await client.GetDataAsync(request); 
         await Response.WriteAsync(formatData(response.Data)) 
         request.Cookie = response.Cookie; 
         request.HasMoreData = response.HasMoreData; 
        } 
    
        return Ok(); 
    } 
    
  • 我連續使用異步在這種方法進行數據呼叫,但是這意味着線程將被切換了很多次的挫折感。這樣做是否異步實際上給我一個性能下降?是否應該全部是同步的(方法簽名和數據調用)?

回答

1

難道是更有效的數據的每一個緩衝區格式化爲CSV在循環,並將其寫入到響應每次流,或者最好等到最終像我現在在做什麼?

您可以,但除非數據是太大,不適合到內存中,我不會推薦它。

流媒體的優勢在於數據不必適應內存,客戶端可以逐漸接收數據。

流式傳輸的缺點是必須在流開始之前發送HTTP響應代碼,因此在流式傳輸開始後無法通知客戶端錯誤。因此,如果其中一個GetDataAsync調用失敗,客戶端仍然會獲得200 OK,但是其數據意外中斷。

我在這種方法中不斷地使用async進行數據調用,但這意味着線程將會轉換很多次。這樣做是否異步實際上給我一個性能下降?是否應該全部是同步的(方法簽名和數據調用)?

否; ASP.NET Core上的異步代碼具有與同步代碼相同或更少的線程切換。