FileIO.ReadTextAsync偶尔会挂起

时间:2012-05-22 10:52:17

标签: c# windows-runtime

我只是尝试使用WinRT,我正在创建的一个演示应用程序是一个基本的“记事本”样式应用程序,可以加载/保存到本地存储。虽然我熟悉构建WinRT应用程序的正确async方法,但我的演示应用程序使用同步Load来保持简单。

问题在于,当拨打Load时,它会在3次中有2次播放,其余时间应用会在通话中挂起var result = await FileIO.ReadTextAsync(storageFile);

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; }
    }
}

我在这里做了一件非常愚蠢的事吗?

FWIW,我尝试将Load更改为仅明确阻止每一步,这样可以将挂起提高到20,但我仍然不明白为什么它会挂起......

public string Load()
{
    var storageFile = LocalFolder.GetFileAsync(FileName).AsTask().Result;
    var result = FileIO.ReadTextAsync(storageFile).AsTask().Result;

    return result;
}

2 个答案:

答案 0 :(得分:4)

  

虽然我熟悉构建WinRT应用程序的正确async方法,但我的演示应用程序使用同步Load来保持简单。

不是真的。与异步代码同步混合非常复杂。在任何地方使用async都简单得多。

async方法在等待任务后继续执行时,它将默认返回其原始上下文。 (我在async/await blog post)中更详细地介绍了这一点。某些上下文(例如UI上下文)仅允许单个线程;如果该线程被阻止(例如,在Task.Result上),则async方法无法进入该上下文以完成其执行。这会导致死锁。

了解更多信息:

这种僵局很有名,实际上已经被微软演示了:

答案 1 :(得分:0)

尝试使用ConfigureAwait(false)和await操作,可能ReadTextAsync不是线程安全的,所以当await结束并返回UI线程时它会挂起UI线程。