Доброго времени суток.
У меня возникла проблема: есть простое приложение, которое копирует файлы из одного места в другое.
Есть простенький GUI который показывает процесс копирования.
Соответственно, чтобы GUI не тормозил, собственно копирование осуществляется в отдельном потоке.
Для передачи информационных сообщений в правильный поток используется SynchronizationContext.Current.
Иногда это приложение сваливается в
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
в System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
в System.Windows.Forms.Control.DefWndProc(Message& m)
в System.Windows.Forms.Control.WndProc(Message& m)
в System.Windows.Forms.TextBoxBase.WndProc(Message& m)
в System.Windows.Forms.RichTextBox.WndProc(Message& m)
в System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
в System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Иногда просто зависает.
Контекст создается так:
SynchronizationContext context;
public CopyProgressForm()
{
InitializeComponent();
context = SynchronizationContext.Current;
}
Передача информационных сообщений происходит так:
private void AppendText(string text)
{
context.Post(delegate(object state)
{
rtbLog.AppendText((string)state);
rtbLog.SelectionStart = rtbLog.TextLength;
rtbLog.SelectionLength = 1;
rtbLog.ScrollToCaret();
}, text);
}
Если прицепиться отладчиком и сказать Break All, то будет подсвечена строка
rtbLog.AppendText((string)state);
Я пытался сделать (в методе AppendText(string text)):
1. Вместо SynchronizationContext.Post использовать SynchronizationContext.Send
2. Вместо SynchronizationContext использовать this.InvokeRequired и this.Invoke,
3. Синхронизировать доступ с помощью Mutex.WaitOne\Mutex.ReleaseMutex и lock(object).
4. Вместо SynchronizationContext использовать AsyncOperation
Но проблема так и не решилась.
Может кто сталкивался и побеждал подобное. Может я где чего недопонимаю.
Помогите пожалуйста. Буду очень признателен.
PS: Воспроизвести ошибку можно если очень часто вызывать метод AppendText из другого потока и при этом постоянно дергать окошко приложения (передвигать, менять размеры).