首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步StreamWriter循环在BufferBlock为空时停止写入

异步StreamWriter循环在BufferBlock为空时停止写入
EN

Stack Overflow用户
提问于 2013-06-17 09:54:07
回答 1查看 1.5K关注 0票数 4

最近,我将LogManager类从static类转换为singleton类,以便更容易地在WPF中绑定(尽管我认为在此之前也存在这个问题)。在检查了每件事后,我注意到了一些奇怪的事情。我用来将日志写入文件并将其发送到视图的SaveLoop任务并不像我想象的那样工作。

在视图中,它们几乎立即被添加,如果我关闭应用程序,SaveLoop任务将被取消,我可以在创建的文件中查看日志。但是,当应用程序崩溃时(或者我在Visual中按下停止按钮),带有日志的文件包含大约8-10个日志,比视图中的实际日志数要少。

我注意到的是,当BufferBlock不包含更多日志时,作者停止编写(在消息的中间),只有在添加了新日志时才会继续。

是因为BufferBlock停止了任务中的每个异步操作,因为它没有更多的项可供提供吗?

这是运行应用程序时控制台中的输出( LogStatus消息是另一个循环任务,它检测到在过去1000毫秒内发生了任何变化):

代码语言:javascript
复制
12345678
12345678
12345678
1Setting LogStatus=Idle

我真的不知道如何处理这个问题,如果有人能帮助我,那将是非常感谢!

SaveLoop任务(控制台输出仅用于调试):

代码语言:javascript
复制
private async Task SaveLoop(CancellationToken cancel)
{
    string logPath = "logs\\";
    string logFile = _startTime.ToString("yyyy-MM-dd_HH-mm-ss") + ".log";
    string fullPath = Path.Combine(logPath, logFile);

    if (!Directory.Exists(logPath))
        Directory.CreateDirectory(logPath);

    using (FileStream fileStream = new FileStream(fullPath, FileMode.Append, FileAccess.Write, FileShare.Read, 8192, useAsync: true))
    {
        using (StreamWriter writer = new StreamWriter(fileStream))
        {
            while (true)
            {
                LogMessage logMessage = null;

                try
                {
                    Console.Write("1");
                    logMessage = await _logQueue.ReceiveAsync(cancel).ConfigureAwait(false);

                    Console.Write("2");
                    await writer.WriteAsync(String.Format("({0}) ", logMessage.LogID)).ConfigureAwait(false);
                    Console.Write("3");
                    await writer.WriteAsync(String.Format("[{0}][{1}] ", logMessage.Time.ToString("HH:mm:ss:fff"), logMessage.Level.ToString())).ConfigureAwait(false);
                    Console.Write("4");
                    await writer.WriteAsync(logMessage.Message).ConfigureAwait(false);
                    Console.Write("5");
                    await writer.WriteLineAsync(String.Format(" ({0} - {1})", logMessage.Method, logMessage.Location)).ConfigureAwait(false);

                    Console.Write("6");

                    AddLogToCollections(logMessage);

                    Console.Write("7");
                    _timeout = 10;

                    if (cancel.IsCancellationRequested)
                    {
                        Console.WriteLine("0");
                        break;
                    }

                    Console.WriteLine("8");
                }
                catch (TaskCanceledException tce)
                {
                    Console.WriteLine("Task canceled!");
                    Console.WriteLine("{0} {1}", tce.Message, tce.Source);
                    break;
                }
                catch (Exception e)
                {
                    Console.WriteLine("{0} {1}", e.Message, e.Source);
                    Console.WriteLine("{0}", e.StackTrace);
                    if (logMessage != null)
                    {
                        Console.WriteLine("Log: {0}", logMessage.ToString());
                    }
                }
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-17 11:06:09

这与Dataflow块无关。之所以会出现这种情况,是因为StreamWriterFileStream使用缓冲来提高效率。因此,您应该做的是在循环的末尾添加await writer.FlushAsync(),它清空缓冲区并将数据写入磁盘。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17144739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档