在我們的應用程序中,我們有一個跟蹤窗口,我們可以在客戶端位置啓用一些調試功能,它被認爲是靜態庫。MTA線程中的日誌記錄窗口:訪問衝突
問題是,當有很多日誌消息進入窗口時,它會崩潰並出現AccessViolation錯誤。代碼崩潰的代碼鏈接是RichTextBox.AppendText(..,..,..)。
這裏是我們創建窗口的地方。
public static void Start(Form parent)
{
if (_runningThread == null || !_runningThread.IsAlive)
{
_runningThread = new Thread(() =>
{
_traceView = new TraceView(parent) { Text = "Tracing ~ " + parent.Text };
Application.Run(_traceView);
});
_runningThread.SetApartmentState(ApartmentState.MTA);
_runningThread.Start();
}
}
,這裏是被我們寫一行文本框
public void Write(string line, Color color)
{
try
{
_msgQueue.Enqueue(new Tuple<string, Color>(line, color));
MethodInvoker gui = delegate
{
try
{
// Was getting an overflow so trim out some lines
if (uiTrace.Lines.Length > 5000)
{
uiTrace.Lines = new string[0];
uiTrace.SelectionStart = uiTrace.TextLength;
Application.DoEvents();
}
while (_msgQueue.Count != 0)
{
bool retry;
var count = 0;
do
{
try
{
count++;
if (_indent < 0)
_indent = 0;
var msg = _msgQueue.Dequeue();
var selectionStart = uiTrace.TextLength;
uiTrace.AppendText(string.Format("[{0}] {1}{2}", _stopwatch.ElapsedMilliseconds, string.Empty.PadLeft(_indent * 4), msg.Item1));
uiTrace.Select(selectionStart, uiTrace.TextLength);
uiTrace.SelectionColor = msg.Item2;
uiTrace.SelectionStart = uiTrace.TextLength;
uiTrace.ScrollToCaret();
retry = false;
}
catch (Exception)
{
retry = true;
}
} while (retry && count < 5);
}
}
catch (Exception)
{
// We don't care about exceptions in here, for now anyway
}
};
if (uiTrace.InvokeRequired && !uiTrace.Disposing && !uiTrace.IsDisposed)
{
uiTrace.BeginInvoke(gui);
return;
}
gui();
}
catch (Exception)
{
// QIT_Backoffice.Processes.Errors.ErrorHandler.WriteErrorLog(Sources.SourceEnum.External, ex, "Error writing to trace");
}
}
我真的不知道怎麼去解決這一個,我想調用的BeginInvoke()是被需要的。
尋找任何可能的幫助,或者如果有人知道可以更好地處理這個問題的第三方工具,我很高興看到這一點。
由於'TraceView'似乎是一種形式,它爲什麼在MTA運行?你爲什麼叫'DoEvents'?什麼線程是從我這裏調用的'Write'?沒有足夠的信息。 – Jon
我會考慮使用[OutputDebugString](http://www.pinvoke.net/default.aspx/kernel32.outputdebugstring)和[DebugView](http://technet.microsoft.com/en-au/sysinternals/bb896647 .aspx)之前去一個自定義的UI路由。 – Noseratio
我認爲訪問衝突是由重入造成的。在先前調用uiTrace.AppendText之前,可能會從另一個線程*調用'Write',最終再次重新進入uiTrace.AppendText。檢查我的答案,找出解決這個問題的辦法。 – Noseratio