【问题标题】:ASP.NET MVC controller stucked at reading a fileASP.NET MVC 控制器卡在读取文件时
【发布时间】:2013-08-31 09:01:26
【问题描述】:

我有一个非常简单的控制器,它尝试使用 await/async 方法读取本地文件的内容。使用 XUnit 或从控制台应用程序测试它就像一个魅力。 但是当从以下控制器使用时,应用程序会卡在 await reader.ReadToEndAsync() 并且永远不会回来。

任何想法可能是错的! (会不会和一些同步上下文有关?)

控制器:

 public ActionResult Index()
 {
    profiles.Add(_local.GetProfileAsync(id).Result);
    return View(profiles);
 }

GetProfileAsync 方法看起来像:

public override async Task<Profile> GetProfileAsync(long id)
{
    // Read profile
    var filepath = Path.Combine(_directory, id.ToString() , "profile.html");
    if (!File.Exists(filepath))
        throw new FileNotFoundException(string.Format("File not found: {0}", filepath));
    string content;
    using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
    {
        using (var reader = new StreamReader(fs))
        {
            content = await reader.ReadToEndAsync();
        }
    }
 ...
    return profile;
 }

【问题讨论】:

    标签: c# asp.net-mvc async-await


    【解决方案1】:

    是的,这是一个同步上下文问题。您通过调用Result 而不是使用await 导致死锁;我解释这个in detail on my blog

    总之,await 在恢复 async 方法时默认会尝试重新进入上下文。但是 ASP.NET 上下文一次只允许一个线程进入,并且该线程在调用 Result 时被阻塞(等待 async 方法完成)。

    要解决此问题,请使用 await 而不是 Result

    public async Task<ActionResult> Index()
    {
      profiles.Add(await _local.GetProfileAsync(id));
      return View(profiles);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      相关资源
      最近更新 更多