C# FileIO.ReadTextAsync偶尔挂起

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来保持简单 不是真的。将同步

我只是在试验WinRT,我正在创建的一个演示应用程序是一个基本的“记事本”风格的应用程序,可以加载/保存到本地存储。虽然我熟悉构建WinRT应用程序的适当
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;
}