C# FileIO.ReadTextAsync偶尔挂起
我只是在试验WinRT,我正在创建的一个演示应用程序是一个基本的“记事本”风格的应用程序,可以加载/保存到本地存储。虽然我熟悉构建WinRT应用程序的适当C# FileIO.ReadTextAsync偶尔挂起,c#,windows-runtime,C#,Windows Runtime,我只是在试验WinRT,我正在创建的一个演示应用程序是一个基本的“记事本”风格的应用程序,可以加载/保存到本地存储。虽然我熟悉构建WinRT应用程序的适当async方法,但我的演示应用程序使用同步Load来保持简单 问题是,当调用Load时,3次中有2次有效,其余时间应用程序挂起调用var result=wait FileIO.ReadTextAsync(storageFile) 虽然我熟悉构建WinRT应用程序的适当async方法,但我的演示应用程序使用同步Load来保持简单 不是真的。将同步
async
方法,但我的演示应用程序使用同步Load
来保持简单
问题是,当调用Load
时,3次中有2次有效,其余时间应用程序挂起调用var result=wait FileIO.ReadTextAsync(storageFile)代码>
虽然我熟悉构建WinRT应用程序的适当async
方法,但我的演示应用程序使用同步Load
来保持简单
不是真的。将同步代码与异步代码混合在一起非常复杂。到处使用async
要简单得多
当一个async
方法在等待任务后继续执行时,默认情况下它将返回到其原始上下文。(我将在我的报告中更详细地介绍这一点)。某些上下文(如UI上下文)只允许单个线程;如果该线程被阻塞(例如,在Task.Result
上),则async
方法无法进入该上下文以完成其执行。这会导致死锁
有关更多信息:
- 在上下文捕获和恢复方面有很多细节
- 并行团队博客上的Stephen Toub有另一篇博文,详细解释了这种特殊的死锁情况
- 我在年为这种僵局写了详尽的答案
此死锁非常著名,实际上已由Microsoft演示:
尝试将ConfigureAwait(false
)与wait操作一起使用,可能是ReadTextAsync
不是线程安全的,因此它将在wait完成时挂起UI线程并返回UI线程。您没有做任何事情来确保WriteTextAsync()完成。坏主意。Hans,跳过WriteTextAsync前面缺少waits关键字的事实,是什么使加载无法按预期工作?
public class ContentStorage : IContentStorage
{
private const string FileName = "contents.txt";
public string Load()
{
return LoadAsync().Result;
}
public void Save(string content)
{
SaveAsync(content);
}
private static async Task<string> LoadAsync()
{
var storageFile = await LocalFolder.GetFileAsync(FileName);
var result = await FileIO.ReadTextAsync(storageFile);
return result;
}
private static async void SaveAsync(string content)
{
var storageFile = await LocalFolder.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);
FileIO.WriteTextAsync(storageFile, content);
}
private static StorageFolder LocalFolder
{
get { return ApplicationData.Current.LocalFolder; }
}
}
public string Load()
{
var storageFile = LocalFolder.GetFileAsync(FileName).AsTask().Result;
var result = FileIO.ReadTextAsync(storageFile).AsTask().Result;
return result;
}