• .NET4.5新功能:异步文件 I/O


    异步操作可以执行大量占用资源的 I/O 操作,而不必阻止主线程。 此性能注意事项非常重要。 windows Metro style app 或 desktop app 耗时的流操作会阻止 UI 线程并将您的应用程序显示的位置,就象它不起作用。

    从开始 .NET Framework 4.5 RC, I/O 类型包括异步方法简化异步操作。 异步方法在其名称中包含 Async ,例如 ReadAsyncWriteAsyncCopyToAsyncFlushAsyncReadLineAsyncReadToEndAsync 这些异步方法对流类,如 StreamFileStreamMemoryStream以及用于读取或写入使用至流 (如 TextReaderTextWriter的类。

    在 .NET framework 4 和早期版本中,必须使用之类的方法 BeginReadEndRead 实现异步 I/O 操作。 这些方法可在 .NET Framework 4.5 RC 支持旧版代码;但是,异步方法帮助您更轻松地实现异步 I/O 操作。

    从开始 Visual Studio 2012 RC, Visual Studio 为异步编程提供两个关键字:

    • Async (Visual Basic) 或 (c#) async 修饰符,用于指示方案包含一个异步操作。

    • Await (Visual Basic) 或 (c#) await 运算符,会应用于异步方法的结果。

    如下面的示例所示,若要实现异步 I/O 操作,请使用异步方法结合使用这些关键字,。 有关更多信息,请参见 异步编程与异步和等待 (C# 和 Visual Basic)

    下面的示例演示如何使用复制文件的两 FileStream 对象异步从一个目录到另一个。 请注意 Button 控件的 Click 事件处理程序标记 async 修饰符,因为它调用异步方法。

    using System;
    using System.Threading.Tasks;
    using System.Windows;
    using System.IO;
    
    namespace WpfApplication
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private async void Button_Click(object sender, RoutedEventArgs e)
            {
                string StartDirectory = @"c:\Users\exampleuser\start";
                string EndDirectory = @"c:\Users\exampleuser\end";
    
                foreach (string filename in Directory.EnumerateFiles(StartDirectory))
                {
                    using (FileStream SourceStream = File.Open(filename, FileMode.Open))
                    {
                        using (FileStream DestinationStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf('\\'))))
                        {
                            await SourceStream.CopyToAsync(DestinationStream);
                        }
                    }
                }
            }
        }
    }

    下一个示例与前一个示例相似,但使用 StreamReaderStreamWriter 对象读取和写入文本文件的内容异步。

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        string UserDirectory = @"c:\Users\exampleuser\";
    
        using (StreamReader SourceReader = File.OpenText(UserDirectory + "BigFile.txt"))
        {
            using (StreamWriter DestinationWriter = File.CreateText(UserDirectory + "CopiedFile.txt"))
            {
                await CopyFilesAsync(SourceReader, DestinationWriter);
            }
        }
    }
    
    public async Task CopyFilesAsync(StreamReader Source, StreamWriter Destination) 
    { 
        char[] buffer = new char[0x1000]; 
        int numRead; 
        while ((numRead = await Source.ReadAsync(buffer, 0, buffer.Length)) != 0) 
        {
            await Destination.WriteAsync(buffer, 0, numRead);
        } 
    } 

    使用 StreamReader 类的实例,下一个示例演示用于打开文件为 Metro style app 的 Stream 的代码隐藏文件和 XAML 文件之后和读取其内容。 它使用异步方法打开文件以流和读取其内容。

                         using System;
    using System.IO;
    using System.Text;
    using Windows.Storage.Pickers;
    using Windows.Storage;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace ExampleApplication
    {
        publicsealedpartialclass BlankPage : Page
        {
            public BlankPage()
            {
                this.InitializeComponent();
            }
    
            privateasyncvoid Button_Click_1(object sender, RoutedEventArgs e)
            {
                StringBuilder contents = new StringBuilder();
                string nextLine;
                int lineCounter = 1;
    
                var openPicker = new FileOpenPicker();
                openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                openPicker.FileTypeFilter.Add(".txt");
                StorageFile selectedFile = await openPicker.PickSingleFileAsync();
    
                using (StreamReader reader = new StreamReader(await selectedFile.OpenStreamForReadAsync()))
                {
                    while ((nextLine = await reader.ReadLineAsync()) != null)
                    {
                        contents.AppendFormat("{0}. ", lineCounter);
                        contents.Append(nextLine);
                        contents.AppendLine();
                        lineCounter++;
                        if (lineCounter > 3)
                        {
                            contents.AppendLine("Only first 3 lines shown.");
                            break;
                        }
                    }
                }
                DisplayContentsBlock.Text = contents.ToString();
            }
        }
    }
  • 相关阅读:
    087 类的继承
    086 一切皆对象
    085 对象的绑定方法
    在菜鸟教程学 HTML(一)
    生成输出 URL(16.2)
    创建分部视图(7.6.3)
    显示页面链接(7.5.1)
    NuGet 控制台代码
    浏览器对应用程序的根URL发出请求时所发生的情况(结合 DI)
    第 6 章 —— 依赖项注入(DI)容器 —— Ninject
  • 原文地址:https://www.cnblogs.com/love007/p/2534633.html
Copyright © 2020-2023  润新知