ASP.NET MVC控制器在读取文件时出错
本文关键字:文件 出错 读取 NET MVC 控制器 ASP | 更新日期: 2023-09-27 18:29:52
我有一个非常简单的控制器,它尝试使用wait/async方法读取本地文件的内容。用XUnit或控制台应用程序测试它就像一个魅力。但是当从下面的控制器使用时,应用程序会被阻塞在等待读取器上。ReadToEndAsync(),然后再也不会回来。
知道可能出了什么问题吗!(这可能与某些同步上下文有关吗?)
控制器:
public ActionResult Index()
{
profiles.Add(_local.GetProfileAsync(id).Result);
return View(profiles);
}
GetProfileSync方法看起来像:
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;
}
是的,这是一个同步上下文问题。您调用Result
而不是使用await
导致死锁;我在博客上详细解释了这一点。
总之,默认情况下,await
在恢复async
方法时将尝试重新输入上下文。但是ASP.NET上下文一次只允许一个线程进入,并且该线程在对Result
的调用中被阻止(等待async
方法完成)。
要解决此问题,请使用await
而不是Result
:
public async Task<ActionResult> Index()
{
profiles.Add(await _local.GetProfileAsync(id));
return View(profiles);
}