私たちのアプリには、デバッグを許可するためにクライアントの場所で有効にできるトレース ウィンドウがあり、静的ライブラリを介してアクセスされます。
問題は、ウィンドウに大量のログ メッセージが送信されると、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()を呼び出すことが必要だと思いました。
可能なヘルプを探しているか、これをより適切に処理できるサードパーティのツールを誰かが知っている場合は、喜んでそれを見てください.