[英]Race condition / TextWriterTraceListener
從多線程登錄到文件時,我有一種看起來像競爭狀況的東西。
1)我有一個自定義記錄器類(ConfigurableTraceLogger),該類由應用程序中的多個線程共享。 它有很多包裝函數,都調用了主核心函數
protected void TraceData(String category, TraceEventType type, EventId id, string prefix, string format)
{
foreach (TraceListener item in _listeners)
{
IConfigurableTraceListener cl = item as IConfigurableTraceListener;
if (cl != null && cl.Category == category.ToLower())
{
if (DisplayMethodName)
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
else
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, format);
item.Flush();
}
}
}
如您所見,我的類只是在集合_listeners中存儲了不同的TraceListner-derved類。 基本上只有控制台和文本文件偵聽器。 TraceData會執行的操作使用類別名稱(即啟動日志記錄)並找到正確的偵聽器。 所有偵聽器均由配置文件名定義
現在,我在集合中也有我的自定義監聽器
public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener
該自定義類除一個屬性外不覆蓋任何內容。
protected override string[] GetSupportedAttributes()
{
return new string[] { "category" };
}
5至10分鍾后啟動應用程序時,通話異常
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
例外是在說:
“復制內存時檢測到可能的I / O競爭狀態。默認情況下,I / O包不是線程安全的。在多線程應用程序中,必須以線程安全的方式訪問流,例如TextReader的返回的線程安全包裝器或TextWriter的Synchronized方法。這也適用於StreamWriter和StreamReader之類。”
在那之后,我在同一通電話上多次出現第二次異常
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
例外
計數不能小於零。 參數名稱:count堆棧跟蹤:“位於System.IO.StreamWriter.Write(字符串值)\\ r \\ n,位於System.String.CopyTo(Int32 sourceIndex,Char []目標,Int32 destinationIndex,Int32計數)\\ r \\ n System.Diagnostics.TraceListener.WriteHeader(System.Diagnostics.TraceListener.TraceData(TraceEventCache eventCache,String)上的System.Diagnostics.TextWriterTraceListener.Write(String message)\\ r \\ n(String source,TraceEventType eventType,Int32 id)\\ r \\ n源,TraceEventType eventType,Int32 id,對象數據)\\ r \\ n位於Jfc.Configuration.ConfigurableTraceLogger.TraceData(字符串類別,TraceEventType類型,EventId ID,字符串前綴,字符串格式,Object [] args)“
在我看來,我的課程以及對TraceData的調用也不是線程安全的。 但是據說ConfigurableTextWriterTraceListener畢竟是線程安全的。 但是,我在運行時檢查了我的TextWriterTraceListener派生類的IsThreadSafe屬性,它為false。 我正在嘗試找出問題所在。
這意味着說什么-您的TraceListener不是線程安全的,並且從多個線程訪問時會中斷。 您需要使您的偵聽器線程安全,或找到一種方法來確保只有一個線程可以訪問任何特定實例。
使它們線程安全的一種方法是使用同步隊列並使所有調用將數據項排隊到隊列中,而“真實” traceListener使它們出隊並在單獨的線程中將它們寫出。
您還必須注意偵聽器的字典-更新字典不是線程安全的,但是如果在應用上一次更新之前從未訪問過字典,則可以按原樣保留它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.