[C#][Grafika][Wątki]: Problem z wątkami

0

Witam wszystkich :]
No więc tak (bez długich wstępów): piszę sobie jakąśtam aplikację graficzną, i ulepszyłem ją niedawno w taki sposób: dodałem rysowanie w oddzielnym wątku, coby nie cięło, a i żeby skalowanie formy (na przykład) nie wstrzymywało odrysowywania. Wygląda to tak (wybrane fragmenty z klasy rysującej):

        bool AllowRender = false;

///...

        private void InitThread()
        {
            drawThread = new Thread(new ThreadStart(RenderByThread));
        }

///...

        // Tylko ona jest wywoływana z okna głównego, pozwala ona niejako wątkowi kontynuować rysowanie.
        public void Render()
        {
            if (drawThread == null) return;

            AllowRender = true;
            if (!drawThread.IsAlive) drawThread.Start();
        }

///...

        // Stąd zaczyna wątek.
        private void RenderByThread()
        {
            Bitmap threadBufor = new Bitmap(500, 500); //przykładowo

            while (AllowRender)
            {
                Graphics g = Graphics.FromImage(threadBufor);
                AllowRender = false;

                // Tutaj funkcje rysujące, pozwoliłem sobie wyciąć...

                bitmap = threadBufor;
                g.Dispose();
            }

            threadBufor.Dispose();
            drawThread.Join();
        }

Przy każdym uruchomieniu występuje po paru sekundach wyjątek (nie wspominając że obraz miga, chociaż przed wprowadzeniem wątku nie migał - tzn nie miga tylko... jakby wyświetlał obraz narysowany w połowie).
No i kilka z występujących:

if (!drawThread.IsAlive) drawThread.Start(); - Thread is running or terminated; it cannot restart. Czasami się pojawia. Możliwe że chodzi o "terminated" (jest pewno miejsce w którym samodzielnie go ubijam),ale co zrobić żeby uruchomić go ponownie?

g.DrawImage(drawing.GetBitmap, 0, 0); - Parametr is not valid I tego właśnie nie rozumiem - Co się może metodzie drawImage nie podobać w bitmapie? Czasami też w tym samym miejscu pojawia się "Object is currently in use elsewhere." edit: wiem co to oznacza, ale nie mogę znaleźć nigdzie miejsca gdzie mógłbym go używać. Z tego co czytałem przypisania klas (zawsze przez referencję) są bezpieczne, a nic innego z nią nie robię.

No i pytanie: Czy widać tutaj gdzieś jakieś rażące błędy? Nie wspominając że mam wątpliwości co do ogólnej architektury tego fragmentu kodu (While AllowThread? drawThread.Join();? Powtarzanie drawThread.Start();?)
Z góry zaznaczam że nie znam się na wątkach... i chciałbym się nauczyć.
Koniec.

0

if (!drawThread.IsAlive) drawThread.Start();

Wątek można odpalić tylko jeden raz. Po tym nie możesz wykonać drugi raz Start(). Trzeba stworzyć nowy wątek.


while (AllowRender)
            {
                Graphics g = Graphics.FromImage(threadBufor);
                AllowRender = false;

                // Tutaj funkcje rysujące, pozwoliłem sobie wyciąć...

                bitmap = threadBufor;
                g.Dispose();
            }

Co rzuca się w oczy to jawne Dispose() bez żadnych zabezpieczeń. Gdyby wcześniej się wywaliło - Dispose się nie wywoła. Należy użyć klauzuli using()

0

Poprawiłem to (rzeczywiście, działa), dodałem using, a resztę załatwiło jedno lock i usunięcie dwóch lini kodu. Ale program nadal działa... dziwnie, choć już bez wyjątków. Będę się musiał nad nim pomęczyć. Tak czy inaczej, dziękuje wszystkim (tzn Deti'emu) za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0