gpt4 book ai didi

c# - 当 BufferBlock 为空时,Async StreamWriter Loop 停止写入

转载 作者:行者123 更新时间:2023-11-30 14:59:10 28 4
gpt4 key购买 nike

我最近将我的 LogManager 类从 static 转换为 singleton 类,以便在 WPF 中更容易绑定(bind)(虽然我认为这个问题也存在在这之前)。在检查了所有是否一切正常之后,我发现了一些奇怪的事情。我用于将日志写入文件并将它们发送到 View 的 SaveLoop 任务并不像我想象的那样有效。

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

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

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

这是我运行应用程序时控制台中的输出(LogStatus 消息是另一个循环任务,用于检测在过去 1000 毫秒内是否有任何更改):

12345678
12345678
12345678
1Setting LogStatus=Idle

我真的不知道如何处理这个问题,如果有人能帮助我,我将不胜感激!


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

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());
}
}
}
}
}
}

最佳答案

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

关于c# - 当 BufferBlock 为空时,Async StreamWriter Loop 停止写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17144739/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com