C # WinForms: рисование с одним или несколькими дополнительными потоками. Как? - PullRequest
6 голосов
/ 27 сентября 2011

В случае, если у меня большой рисунок со всеми видами геометрических форм (линии, прямоугольники, круги и т. Д.), Потоке потребуется много времени, чтобы все нарисовать. Но в реальной жизни одно здание строится несколькими работниками. Так что, если чертеж - это здание, а нити - строители, он будет нарисован намного быстрее. Но я хочу знать, как.

Можете ли вы сказать мне, как? Возможно ли это (хотя я уже спрашивал, и ответ был "Да")? Стоит ли его использовать? Каковы риски?

Если есть вопросы, которые я пропустил, расскажите, пожалуйста, о них и ответьте на них.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 27 сентября 2011

Предполагается, что вы используете GDI + и объект System.Drawing.Graphics для рендеринга вашей графики (прямоугольники, круги и т. Д.) На фоновую поверхность рисования (например, System.Drawing.Bitmap Объект): члены экземпляра объекта System.Drawing.Graphics, который вы бы хотелинеобходимо использовать не потокобезопасен . См. Документацию MSDN здесь

Учитывая это, я бы не использовал более одного потока "строителя" для визуализации вашей графики.

Вместо этого я рекомендую сделать всевашего чертежа в System.Drawing.Bitmap объект в одиночном фоновом потоке, а не в нескольких фоновых потоках, если это возможно.Вы можете использовать строку состояния или другой индикатор, чтобы сообщить пользователю, что ваша программа работает в фоновом режиме.

1 голос
/ 27 сентября 2011

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

Тем не менее, стоит проверить, верно ли это утверждение для Graphics также.

Из документов класса System.Drawing.Graphics :

Все открытые статические (Shared в Visual Basic) члены этого типа являются потокамибезопасный.Ни один из членов экземпляра не гарантированно является потокобезопасным.

Не пахнет хорошо: все методы рисования являются членами экземпляра.Вы не можете распределять операции над объектом Graphics по нескольким потокам.

0 голосов
/ 27 сентября 2011

В качестве простого примера вы можете использовать потоки для выполнения нескольких задач с использованием метода делегата ThreadStart, он будет выглядеть примерно так:

        Thread t = new Thread(new ThreadStart(MethodToExecuteOnSecondThread));
        t.Start();
        while (!t.IsAlive)
        {
            //do something to show we're working perhaps?
            UpdateMyGuiWithALoadingBar(); 
        }

Затем ваш второй поток завершается и выполняет ThreadStart() метод делегата, пока основной поток остается отзывчивым.

...