第二十章:异步和文件I/O.(十四)

简介:

保持在后台
Windows运行时实现中的一些FileHelper方法有多个等待运算符来处理一系列异步调用。这是有道理的:流程中的每个步骤必须在下一步执行之前完成。但是,等待的一个特征是它在与其调用的相同线程而不是后台线程上恢复执行。当您获得更新用户界面的结果时,这通常很方便。但是,在FileHelper实现的方法中,这不是必需的。 WriteTextAsync和ReadTextAsync方法体内的所有内容都可以在辅助线程中出现。
Task类有一个名为ConfigureAwait的方法,可以控制等待恢复的线程。如果将false参数传递给ConfigureAwait,则完成的任务将在用于实现该函数的同一工作线程上恢复。如果您想在FileHelper代码中使用它,则需要使用AsTask将Windows运行时方法返回的IAsyncAction和IAsyncOperation对象转换为任务,然后在该Task对象上调用ConfigureAwait。
例如,以下是现有Xamarin.FormsBook.Platform.WinRT项目中WriteTextAsync和ReadTextAsync方法的实现方法:

namespace Xamarin.FormsBook.Platform.WinRT
{
    class FileHelper : IFileHelper
    {
        __
        public async Task WriteTextAsync(string filename, string text)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
           IStorageFile storageFile = await localFolder.CreateFileAsync(filename, 
            CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(storageFile, text);
        }
        public async Task<string> ReadTextAsync(string filename)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            IStorageFile storageFile = await localFolder.GetFileAsync(filename);
            return await FileIO.ReadTextAsync(storageFile);
        }
        __
    }
}

这些方法各有两个等待运算符。 为了使这些方法更有效,您可以使用AsTask和ConfigureAwait将它们更改为:

namespace Xamarin.FormsBook.Platform.WinRT
{
    class FileHelper : IFileHelper
    {
        __
        public async Task WriteTextAsync(string filename, string text)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            IStorageFile storageFile = await localFolder.CreateFileAsync(filename, 
                                                  CreationCollisionOption.ReplaceExisting).
                                                  AsTask().ConfigureAwait(false);
            await FileIO.WriteTextAsync(storageFile, text).AsTask().ConfigureAwait(false);
        }
        public async Task<string> ReadTextAsync(string filename)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            IStorageFile storageFile = await localFolder.GetFileAsync(filename).
                                                AsTask().ConfigureAwait(false);
            return await FileIO.ReadTextAsync(storageFile).AsTask().ConfigureAwait(false);
        }
        __
    }
}

现在,第一个await运算符之后的方法在工作线程中运行,而await不需要切换回用户界面线程只是为了继续该方法。 当使用await从TextFileAsyncPage调用这些方法时,会切换回用户接口线程。
您可能希望将此技术限制为底层库函数,或者包含一系列不访问用户界面对象的await运算符的页面类中的代码。 对于只包含一个从用户界面线程调用的await运算符的函数,该技术没有多大意义,因为切换回用户界面线程必须在某个时间发生,如果不是 发生在库函数中,它将发生在调用库函数的代码中。

目录
相关文章
|
Web App开发 Android开发
第二十章:异步和文件I/O.(二十三)
回到网上在本章之前,本书中唯一的异步代码涉及使用可移植类库WebRequest中唯一可用于此目的的合理类进行Web访问。 WebRequest类使用称为异步编程模型或APM的旧异步协议。 APM涉及两种方法,在WebRequest的情况下,这些方法称为BeginGetResponse和EndGetResponse。
716 0
|
JavaScript Android开发 iOS开发
第二十章:异步和文件I/O.(十二)
虽然每个方法都被定义为返回Task或Task 对象,但是方法的主体没有任何对Task或Task 的引用。相反,返回Task对象的方法只是执行一些工作,然后使用隐式return语句结束该方法。 ExistsAsync方法定义为返回Task 但返回true或false。
785 0