【发布时间】:2021-10-02 22:40:08
【问题描述】:
我认为使用 Parallel.ForEach 时不可能有漂亮的日志。除非有人可以向我展示一些技巧吗?
namespace Parallel_ForEach_Logging
{
class Program
{
private static uint _callCount = 0;
static void Main(string[] args)
{
IEnumerable<int> data = Enumerable.Range(0, 2);
Console.Out.WriteLine("***");
ParallelOptions options = new();
options.MaxDegreeOfParallelism = Environment.ProcessorCount;
Parallel.ForEach(data, options, datum =>
{
PrintNum(datum, _callCount++);
});
Console.Out.Flush();
Console.Out.WriteLine("***");
}
public static void PrintNum(int num, uint callCount)
{
Console.Out.WriteLine($">>> IN {callCount}");
// Console.Out.WriteLine($" {num}");
Console.Out.WriteLine($"<<< OUT {callCount}");
PrintString($"\"{num.ToString()}\"", callCount);
}
public static void PrintString(string str, uint callCount)
{
Console.Out.WriteLine($">>> IN {callCount}");
// Console.Out.WriteLine($" {str}");
Console.Out.WriteLine($"<<< OUT {callCount}");
}
}
}
当我说漂亮的日志时,我想到的是:
>>> IN: Method A
>>> IN : Method 1 called.
<<< OUT: Method 1 done.
>>> IN : Method 2 called.
<<< OUT: Method 2 done.
<<< OUT: Method A done in 32 milliseconds.
>>> IN: Method B
...
这是我目前正在获取的示例日志:
>>> IN 1
>>> IN 0
<<< OUT 0
<<< OUT 1
>>> IN 0
<<< OUT 0
>>> IN 1
<<< OUT 1
注意顶部有两个 IN 背靠背,然后两个 OUT 背靠背。
在代码中,_callCount 是我尝试计算用于缩进的调用深度,但我不知道如何进行这项工作。即使我这样做了,我也不确定如果每个日志条目中没有一百万个空格,我是否能做到。
我知道如果我将 Parallel.ForEach 排除在等式之外,我肯定可以让它工作。
如果这真的不可能完成,我没关系。我只需要一个比我聪明的人这么说。 ;)
【问题讨论】:
-
如果您考虑一下,您创建的问题是您的代码是并行的,但日志接收器是串行的。如果你想美化它,日志也需要是并行的,即它可能需要多列,而不是尝试对行进行排序(行实际上是从过去到未来的时间流,所以要强制那些你必须删除并行性)..如果您要将输出转换为表格,控制台不是一个很好的选择(可以这样做,但很头疼)
标签: c# logging parallel.foreach