使用C#5.0异步读取文件

Sam*_*son 9 c# asynchronous async-await c#-5.0 windows-8

我刚刚开始使用C#的新async功能.我已经阅读了很多关于并行下载的方法,但是在阅读/处理文本文件方面没有任何内容.

我有一个旧脚本,我用来过滤日志文件,并认为我有一个升级它.但是我不确定我对新async/ await语法的使用是否正确.

在我的脑海中,我看到这一行逐行读取文件并将其传递给不同的线程进行处理,以便它可以继续而无需等待结果.

我是否正确地思考它,或者实现这个的最佳方法是什么?

static async Task<string[]> FilterLogFile(string fileLocation)
{
    string line;

    List<string> matches = new List<string>();

    using(TextReader file = File.OpenText(fileLocation))
    {        
        while((line = await file.ReadLineAsync()) != null)
        {
            CheckForMatch(line, matches);
        }
    }

    return matches.ToArray();
}
Run Code Online (Sandbox Code Playgroud)

完整的脚本:http://share.linqpad.net/29kgbe.linq

svi*_*ick 9

在我的脑海中,我看到这一行逐行读取文件并将其传递给不同的线程进行处理,以便它可以继续而无需等待结果.

但这不是你的代码所做的.相反,当完成所有读取时,您将(异步)返回一个数组.如果您确实想要逐个异步地返回匹配项,则需要某种异步集合.您可以使用TPL Dataflow中的块.例如:

ISourceBlock<string> FilterLogFile(string fileLocation)
{
    var block = new BufferBlock<string>();

    Task.Run(async () =>
    {
        string line;

        using(TextReader file = File.OpenText(fileLocation))
        {        
            while((line = await file.ReadLineAsync()) != null)
            {
                var match = GetMatch(line);

                if (match != null)
                    block.Post(match);
            }
        }

        block.Complete();
    });

    return block;
}
Run Code Online (Sandbox Code Playgroud)

(您可能需要添加错误处理,可能是通过错误返回的块.)

然后,您将返回的块链接到另一个将处理结果的块.或者您可以直接从块中读取它们(通过使用ReceiveAsync()).


但是看完整个代码,我不确定这种方法对你有用.由于您处理结果的方式(分组然后按每个组中的计数排序),在拥有所有结果之前,您无法对它们做很多事情.