2016-02-26 74 views
-1

我已經去了我的ASP.NET MVC異步控制器中的以下內容。我意識到我在嘗試序列化一項任務。我不想打電話給speakers1.llult結果,因爲這似乎打敗了異步的目的。如何獲得序列化異步結果工作

有沒有適當的異步方式,我可以實現這種序列化?

public async Task<ActionResult> Index() 
    { 
     Task<List<Speaker>> speakersAll1 = 
          _context. 
           Speakers. 
           Include(a => a.Sessions. 
            Select(b => b.Tenant)). 
           ToListAsync(); 

     foreach (var speaker in await speakersAll1) 
     { 
      speaker.ImageUrl = "#"; 
     } 

     byte[] objectDataAsStream; 
     BinaryFormatter binaryFormatter = new BinaryFormatter(); 
     using (MemoryStream memoryStream = new MemoryStream()) 
     { 
      binaryFormatter.Serialize(memoryStream, speakersAll1); 
      objectDataAsStream = memoryStream.ToArray(); 
     } 

     return View("Index", "_Layout", objectDataAsStream.Length); 
    } 

錯誤:

Type 'System.Threading.Tasks.Task`1[[System.Collections.Generic.List`1[[WebApp.Models.Speaker, WebApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' in Assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 

答:每@Gusman改變的BinaryFormatter如下工作:

binaryFormatter.Serialize(memoryStream, await speakersAll1); 
+4

Ehm ...你不能序列化任務,你*不想*序列化任務,你想序列化它的結果,等待任務... – Gusman

回答

0

你根本無法序列化Task,也是你真正想要的是序列化結果。

ASP.NET中的異步方法ASP.NET MVC控制器提供了更好地使用線程池。當一個請求進入時,ASP.NET將其線程池線程中的一個線程分配給該請求。當需要外部I/O操作時,請求線程返回到線程池,直到對外部資源的調用返回。

重要的區別在於異步調用正在進行時請求線程已經返回到線程池。當線程在線程池中時,它不再與該請求相關聯。

異步請求允許較少數量的線程處理大量的請求。

使用此代碼:

public async Task<ActionResult> Index() 
{ 
    List<Speaker> speakersAll1 = await _context.Speakers 
               .Include(a => a.Sessions.Select(b => b.Tenant)) 
               .ToListAsync(); 

    foreach (var speaker in speakersAll1) 
    { 
     speaker.ImageUrl = "#"; 
    } 

    byte[] objectDataAsStream; 
    BinaryFormatter binaryFormatter = new BinaryFormatter(); 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     binaryFormatter.Serialize(memoryStream, speakersAll1); 
     objectDataAsStream = memoryStream.ToArray(); 
    } 

    return View("Index", "_Layout", objectDataAsStream.Length); 
} 

當執行await ... ToListAsync(),該線程被釋放,而不是阻斷,允許其處理另一個請求。

由於您在foreach循環中調用await,因此此代碼與您的代碼相同,但它有點更清晰。

此外,在await之後,您可以使用Result屬性,因爲此時任務已完成。

也許你可以將你的代碼的一部分流移動到async方法,但我很確定這個代碼的瓶頸是數據庫訪問。

+0

你應該解釋他應該做什麼爲什麼不只是傾銷一些代碼。 – Servy

+1

我沒有投票的答案,但我相信這個答案轉換的方法來同步。 –

+0

我編輯我的答案,只是一會兒 –