【问题标题】:Freeze when trying to read a file using PCLStorage尝试使用 PCLStorage 读取文件时冻结
【发布时间】:2014-06-03 10:56:04
【问题描述】:

我在我的项目中使用 PCLStorage 库,以便我可以从我的 PCL 库访问文件系统。我正在尝试按如下方式读取文件:

static async Task<T> LoadAsync<T> (string fileName) where T : class
    {
        var rootFolder = FileSystem.Current.LocalStorage; // debugger stops here
        var m5cacheFolder = await rootFolder.GetFolderAsync (CacheFolderName); // but instead of going to this line, jumps to end of this method
        var userInfoFile = await m5cacheFolder.GetFileAsync (fileName);
        var userInfoFileContent = await userInfoFile.ReadAllTextAsync ();
        var stringReader = new StringReader (userInfoFileContent);
        var serializer = new XmlSerializer (typeof(T));
        return (T)serializer.Deserialize (stringReader);
    }

由于 PCLStorage 是异步的,我想在同步代码中使用它,所以我这样称呼它:

var task = LoadAsync<User> (UserInfoFileName);
user = task.Result;

问题是当我尝试执行此代码时整个应用程序冻结。如上面的 cmets 所述,LoadAsync 方法中的代码没有被执行。我正在使用最新的 Xamarin 3。我的 PCL 库在 Xamarin iOS 项目中被引用。这两个项目都通过 nugget 引用了 PCLStorage。

另一方面,以下代码被正确执行:

static async void PersistAsync (object obj, string fileName)
    {
        var rootFolder = FileSystem.Current.LocalStorage;
        var m5cacheFolder = await rootFolder.CreateFolderAsync (CacheFolderName, CreationCollisionOption.OpenIfExists);
        var userInfoFile = await m5cacheFolder.CreateFileAsync (fileName, CreationCollisionOption.ReplaceExisting);
        var serializer = new XmlSerializer (obj.GetType ());
        var stringWriter = new StringWriter ();
        serializer.Serialize (stringWriter, obj);
        await userInfoFile.WriteAllTextAsync (stringWriter.ToString ());
    }

【问题讨论】:

    标签: c# ios xamarin portable-class-library


    【解决方案1】:

    这总是潜在的灾难:

    var task = LoadAsync<User>(UserInfoFileName);
    user = task.Result;
    

    如果这发生在 UI 线程中,那么您基本上会阻塞 UI 线程,直到任务完成 - 但任务也需要在 UI 线程上执行其延续。你陷入了僵局。

    基本上,您应该尝试构建应用程序以更多地采用异步。您可以使用Task.ConfigureAwait() 来安排LoadAsync 中的延续以在线程池线程上执行,但是您仍然会阻塞UI,直到它完成,这违背了精神异步性。

    异步有点像病毒——如果你试图让应用程序的一个部分异步,你会遇到困难。您需要一直保持异步,至少在 UI 操作方面。

    (顺便说一句,如果您阻止等待PersistAsync 返回的任务,您将遇到类似的问题。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 1970-01-01
      相关资源
      最近更新 更多