FileIO.ReadTextAsync偶尔挂起 [英] FileIO.ReadTextAsync occasionally hangs

查看:155
本文介绍了FileIO.ReadTextAsync偶尔挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是尝试的WinRT和一个演示程序我创建是一个基本的记事本风格的应用程序加载哪些/保存到本地存储。虽然我熟悉正确的异步办法构建WinRT的应用程序,我的演示应用程序是使用同步加载来让事情变得简单。



现在的问题是,当一个呼叫到加载做,它的作品了3 2次的应用程序在调用 VAR结果挂起其余时间=等待FileIO.ReadTextAsync(storageFile);

 公共类ContentStorage:IContentStorage 
{
私人常量字符串文件名=contents.txt;

公共字符串的load()
{
返回LoadAsync()结果。
}

公共无效保存(字符串内容)
{
SaveAsync(内容);
}

私有静态异步任务<串GT; LoadAsync()
{
VAR storageFile =等待LocalFolder.GetFileAsync(文件名);
VAR的结果=等待FileIO.ReadTextAsync(storageFile);

返回结果;
}

私有静态异步无效SaveAsync(字符串内容)
{
VAR storageFile =等待LocalFolder.CreateFileAsync(文件名,CreationCollisionOption.ReplaceExisting);

FileIO.WriteTextAsync(storageFile,内容);
}

私有静态StorageFolder LocalFolder
{
{返回ApplicationData.Current.LocalFolder; }
}
}



我做得非常愚蠢的吗?



FWIW,我尝试改变加载来只是每一步明确禁止,这提高了吊至1比20,但我还是不明白为什么它挂在所有...

 公共字符串的load()
$ { b $ b VAR storageFile = LocalFolder.GetFileAsync(文件名).AsTask()结果。
VAR的结果= FileIO.ReadTextAsync(storageFile).AsTask()结果。

返回结果;
}


解决方案

虽然我熟悉正确的异步办法构建WinRT的应用程序,我的演示应用程序是使用同步加载让事情变得简单。




真的不。混合同步异步代码是非常复杂的。这是简单得多只使用异步无处不在。



当一个异步法任务的等待后继续执行,将默认恢复到原来的环境。 (我更详细的我 异步<支付本/ code> / 的await 博客文章)。某些情况下(如UI上下文)只允许一个线程;如果线程被阻塞(例如,在 Task.Result ),那么异步方法不能进入这一背景下完成它的执行。这导致死锁



有关详细信息:





这僵局足够有名,它实际上是被微​​软demo'd:




I'm just experimenting with WinRT and one demo app i'm creating is a basic "notepad" style app which loads/saves to local storage. Whilst I'm familiar with the proper async approach for building WinRT apps, my demo app is using a synchronous Load to keep things simple.

The problem is that when a call is made to Load, it works 2 out of 3 times and the rest of the time the app hangs on the call 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; }
    }
}

Am I doing something extraordinarily stupid here?

FWIW, I experimented with changing Load to just explicitly block on each step and this improves the hanging to 1 in 20, but I still don't understand why it's hanging at all...

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

    return result;
}

解决方案

Whilst I'm familiar with the proper async approach for building WinRT apps, my demo app is using a synchronous Load to keep things simple.

Not really. Mixing synchronous with asynchronous code is extremely complex. It's far simpler to just use async everywhere.

When an async method continues execution after waiting for a task, it will return to its original context by default. (I cover this in more detail in my async/await blog post). Some contexts (such as UI contexts) only permit a single thread; if that thread is blocked (e.g., on Task.Result), then the async method cannot enter that context to complete its execution. This causes a deadlock.

For more information:

This deadlock is famous enough that it's actually been demo'd by Microsoft:

这篇关于FileIO.ReadTextAsync偶尔挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆