不确定异步处理文件的正确方法

问题描述 投票:0回答:1

我正在使用此代码在磁盘上写入一组文件:

            var savingTasks = games.Games.Select(t=>{
                            var path = Path.ChangeExtension(Path.Combine(savePath,Path.GetFileName(t.Url)),"pgn");
                            Log.Information($"trying to save game in:{path}");
                            var fs = new FileStream(path,FileMode.CreateNew,FileAccess.ReadWrite);
                            opened.Add(fs);
                            var sr = new StreamWriter(fs);
                            writers.Add(sr);
                            var tsk =  sr.WriteAsync(t.Pgn);
                            return tsk;
                            });
            try
            {
                await Task.WhenAll(savingTasks);
                var flushing = writers.Select(u=>u.FlushAsync());
                await Task.WhenAll(flushing);
            }
            catch(Exception e)
            {
                 Log.Fatal($"Cannot write to file:{e}");
                 throw e;
            }
            finally
            {
                 opened.ForEach(s => s.Close());
            }

在某些步骤中,即使代码工作得很好,我也不相信自己正在以最佳方式进行操作。无法说服我的部分是我如何处理关闭:我在Select中创建了一组任务,但是我必须跟踪打开的文件才能关闭它们(最后请参见),并且以类似的方式,我必须管理StreamWriter的集合(请参阅writers)。这不能说服我,是否有更好的方法?

c# asynchronous async-await task-parallel-library
1个回答
0
投票

您使事情复杂化了。

[您应该为usingFileStream使用StreamWriter块,当处理它们时要注意冲洗/关闭。

通过等待WriteAsync而不是返回它生成的Task,将确保您的FileStreamStreamWriter不会被尽快处置:

var savingTasks = games.Games
    .Select(t =>
    {
        var path = Path.ChangeExtension(Path.Combine(savePath,Path.GetFileName(t.Url)),"pgn");
        Log.Information($"trying to save game in:{path}");

        using (var fs = new FileStream(path,FileMode.CreateNew,FileAccess.ReadWrite))
        using (var sr = new StreamWriter(fs))
        {
            await sr.WriteAsync(t.Pgn);
        }
    });

try
{
    await Task.WhenAll(savingTasks);
}
catch(Exception e)
{
    Log.Fatal($"Cannot write to file:{e}");
    throw e;
}
© www.soinside.com 2019 - 2024. All rights reserved.