2016-07-10 2 views
-2

У меня есть пользовательский Paint обработчик, который делает вещи с изображениемИсключение не поймают

void MainForm_Paint(object sender, PaintEventArgs e) { 
    try { 
     int x = (Width - img.Width)/2; 
     int y = (Height - img.Height)/2; 
     e.Graphics.Clear(BackColor); 
     e.Graphics.DrawImage(img, x, y); 
    } catch { } 
} 

try-catch там, потому что img переодеваться каждые 10 мс с помощью System.Timers.Timer
Просто, например, это просто сделать еще один пиксель ряд.

void tick(object sender, System.Timers.ElapsedEventArgs e) { 
    timer.Stop(); 
    try { 
     img?.Dispose(); 
     img = new Bitmap(100, 100); 
     Graphics g = Graphics.FromImage(img); 
     for (int i = 0; i < progress; i++) 
      g.FillRectangle(Brushes.Black, i % 100, (int)Math.Floor(i/100f), 1, 1); 
     if (++progress == 10000) 
      progress = 0; 
     g.Dispose(); 
     Invalidate(); 
    } catch {} 
    timer.Start(); 
} 

Так что иногда форма становится негодным и Paint событие возникает. Это может произойти, когда tick работает над новым изображением, поэтому может быть удален img. Это нормально пропускать Paint в такой ситуации, но код catch просто не будет вызван, поэтому исключение происходит в довольно нечетном месте где-то около progress==3500. Или сбой полностью (если не отладочные)
enter image description here
.NET 4.6.1 (проект 4.0), Win7 x64, VS 2015

+2

Никогда не исправить ошибку в коде с TRY/поймать-эм-все, * особенно * а потоковая ошибка. Используйте ключевое слово 'lock', чтобы ваш код не мог рисовать в то же время, когда вы изменяете изображение. –

+2

_ «Если я продолжу это исключение, все будет хорошо» _ - это противоречит вашему утверждению, что если вы не отлаживаете, процесс «сбой» (т. Е. Завершается ошибкой). В любом случае правильным решением является исправить код, чтобы исключение не было выбрано. Пожалуйста, предоставьте хороший [mcve], который надежно воспроизводит проблему, если вы хотите помочь с этим. –

+0

@PeterDuniho Извините. При написании этого вопроса я сделал несколько изменений в коде и забыл правильно редактировать вопрос – Vlad

ответ

1

Кто-то уже упоминал об этом в комментариях, и должны, вероятно, сделали это ответ, но вы должны использовать ключевое слово блокировки для блокировки объекта изображения, чтобы другой поток не мог попытаться изменить его в одно и то же время.

Вы можете прочитать здесь: https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx