How to Async Files.ReadAllLines and await for results?

前端 未结 5 915
滥情空心
滥情空心 2020-11-29 02:33

I have the following code,

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        button1.IsEnabled = false;

        var s = File.Re         


        
5条回答
  •  日久生厌
    2020-11-29 03:24

    UPDATE: Async versions of File.ReadAll[Lines|Bytes|Text], File.AppendAll[Lines|Text] and File.WriteAll[Lines|Bytes|Text] have now been merged into .NET Core and shipped with .NET Core 2.0. They are also included in .NET Standard 2.1.

    Using Task.Run, which essentially is a wrapper for Task.Factory.StartNew, for asynchronous wrappers is a code smell.

    If you don't want to waste a CPU thread by using a blocking function, you should await a truly asynchronous IO method, StreamReader.ReadToEndAsync, like this:

    using (var reader = File.OpenText("Words.txt"))
    {
        var fileText = await reader.ReadToEndAsync();
        // Do something with fileText...
    }
    

    This will get the whole file as a string instead of a List. If you need lines instead, you could easily split the string afterwards, like this:

    using (var reader = File.OpenText("Words.txt"))
    {
        var fileText = await reader.ReadToEndAsync();
        return fileText.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
    }
    

    EDIT: Here are some methods to achieve the same code as File.ReadAllLines, but in a truly asynchronous manner. The code is based on the implementation of File.ReadAllLines itself:

    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    
    public static class FileEx
    {
        /// 
        /// This is the same default buffer size as
        ///  and .
        /// 
        private const int DefaultBufferSize = 4096;
    
        /// 
        /// Indicates that
        /// 1. The file is to be used for asynchronous reading.
        /// 2. The file is to be accessed sequentially from beginning to end.
        /// 
        private const FileOptions DefaultOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
    
        public static Task ReadAllLinesAsync(string path)
        {
            return ReadAllLinesAsync(path, Encoding.UTF8);
        }
    
        public static async Task ReadAllLinesAsync(string path, Encoding encoding)
        {
            var lines = new List();
    
            // Open the FileStream with the same FileMode, FileAccess
            // and FileShare as a call to File.OpenText would've done.
            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, DefaultOptions))
            using (var reader = new StreamReader(stream, encoding))
            {
                string line;
                while ((line = await reader.ReadLineAsync()) != null)
                {
                    lines.Add(line);
                }
            }
    
            return lines.ToArray();
        }
    }
    

提交回复
热议问题