2016-02-26 79 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

我编辑我的答案,只是一会儿 –