【发布时间】:2013-07-18 17:11:18
【问题描述】:
因此,此示例旨在尝试给出我正在尝试修改的更大系统(即 Orchard CMS)的简单视图。因此,它可能并不完美。
我正在尝试创建一个通过设置管理的日志记录系统。我遇到的问题是检索设置会导致发生日志记录。这是一个希望描述问题的简单示例:
static void Main(string[] args)
{
string[] messages = "this is a test. but it's going to be an issue!".Split(' ');
Parallel.ForEach(messages, Log);
Console.ReadLine();
}
public static void Log(string message)
{
Console.WriteLine(GetPrefix() + message);
}
public static string GetPrefix()
{
Log("Getting prefix!");
return "Prefix: ";
}
这是一个明显的StackOverflowException。但是,我该如何解决呢?在收到GetPrefix 的回复之前,我不能只禁用日志记录,因为我可能会错过日志。 (事实上,在这个简单的例子中,除了第一个之外,我都错过了。)
static void Main(string[] args)
{
string[] messages = "this is a test. but it's going to be an issue!".Split(' ');
Parallel.ForEach(messages, Log);
Console.ReadLine();
}
static bool _disable = false;
public static void Log(string message)
{
if (_disable)
{
return;
}
_disable = true;
Console.WriteLine(GetPrefix() + message);
_disable = false;
}
public static string GetPrefix()
{
Log("Getting prefix!");
return "Prefix: ";
}
(^不好。)
请注意,我目前无法控制 GetPrefix 方法,只能控制 Log 方法。
我不确定是否有办法解决这个问题;我可能需要将设置放在其他地方(例如配置或单独的设置文件)。但是,如果有人有想法或建议,我很乐意尝试任何事情,因为我更愿意保留我现在拥有的设置(在管理界面中)。
【问题讨论】:
-
您必须同步访问
bool _disable。你失去了并行执行,这在这个例子中很好,因为Console.WriteLine无论如何都是同步的。 -
@Ginosaji:这是一个简单的例子,但在实际例子中,同步会对性能产生严重影响。
-
您仍然可以并行处理消息并同步日志记录。正如我所说,
Console.WriteLine无论如何都是同步的,所以锁定bool _disable不会有任何损失。 -
@Ginosaji:
Console.WriteLine没有在真正的解决方案中使用。假设我们不能连续记录 - 它需要能够一次处理许多日志。
标签: c# multithreading circular-dependency