У меня есть куча фоновых событий.
Все они вызывают лог:
private void log(string text, params object[] values)
{
if (editLog.InvokeRequired)
{
editLog.BeginInvoke(
(MethodInvoker)delegate
{
this.log(text, values);
});
}
else
{
text = string.Format(text, values) + Environment.NewLine;
lock (editLog)
{
editLog.AppendText(text);
editLog.SelectionStart = editLog.TextLength;
editLog.ScrollToCaret();
}
}
}
Иногда я получаю это, но иногда нет:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.RichTextBox.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Object& editOle)
at System.Windows.Forms.TextBoxBase.ScrollToCaret()
at Program1.frmMain.log(String text, Object[] values) in
...
...
...
PD: Не всегда останавливайтесь на этой строке, случайным образом будет один из трех случаев использования методов/свойств editLog. Не всегда исключением является throw. Иногда кажется, что вещь замирает. Но не основной пользовательский интерфейс, а просто поток сообщений (то есть: журнал выглядит так, как будто больше никогда не вызывается)
Приложение представляет собой единую форму с фоновым процессом. Я не вижу, что я делаю неправильно с этим ...
ОБНОВЛЕНИЕ:
Я делаю предложение Мангиста, это код (таймер срабатывает на 100 мс). Тот же результат:
private Queue<String> logs = new Queue<String>();
private void timerLog_Tick(object sender, EventArgs e)
{
lock (logs)
{
for (int i = 0; i < logs.Count; i++)
{
editLog.AppendText(logs.Dequeue());
editLog.SelectionStart = editLog.TextLength;
editLog.ScrollToCaret();
}
}
}
private void log(string text, params object[] values)
{
text = string.Format(text, values) + Environment.NewLine;
if (editLog.InvokeRequired)
{
editLog.BeginInvoke(
(MethodInvoker)delegate
{
lock (logs)
{
logs.Enqueue(text);
}
//this.log(text, values);
});
}
else
{
logs.Enqueue(text);
}
}
this
). Всегда используйте элементnew object()
только для блокировки. См. Почему великая идея не так велика. - person Remus Rusanu   schedule 26.06.2012