所以,這個例子試圖給出一個我試圖修改的更大的系統(即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是同步的。 – JosephHirn
@Ginosaji:這是一個簡單的例子,但實際上,同步會對性能產生嚴重影響。 – zimdanen
您仍然可以並行處理這些消息並只是同步日誌記錄。正如我所說,無論如何,Console.WriteLine是同步的,所以你通過鎖定'bool _disable'沒有任何損失。 – JosephHirn