Multithreading

pria

Mitglied
Hallo,
ich weiss , dass das Thema schon öfter angesprochen wurde , aber es ist nun mal so , dass ich das was hier oder auch bei Mircosoft zu diesem Thema steht , für mich absolut nicht zu kapieren ist :mad:

Daher , ich habe ein Schiebepuzzle erstellt , und nun möchte ich die Threadmethode game so einrichten , dass ich zuvor erstellte Panels durcheinanderwürfle und dann das Spiel starte.
Nun gibt es aber immerwieder die allseits bekannte Meldung "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde".
Ich hab wirklich keinen Plan , wie das mit dem Controls.Inoke() gehen soll.

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace PuzzleBox
{
    public partial class Game : Form
    {
        PuzzleBox p;
        Image bild;
        int level;
        Graphics[] g;
        Panel[] pl;
        bool abort = false;
        Random r = new Random();
        
        public Game(PuzzleBox p,Image bild,int level)
        {
            InitializeComponent();
            this.p = p;
            this.bild = bild;
            this.level = level;
            abort = false;

            this.KeyPress += new KeyPressEventHandler(Game_KeyPress);
            this.MouseMove += new MouseEventHandler(Game_MouseMove);

            levelINI(this.level, this.bild);
            
            paintKomponents();

            Thread th = new Thread(paintRepaint);
            th.Start();

            Thread th2 = new Thread(game);
            th2.Start();
        }

        void Game_MouseMove(object sender, MouseEventArgs e)
        {
           
        }

        void Game_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((int)e.KeyChar == (int)Keys.Escape)
            {
              abort = true;
              this.Hide();
              p.Show();
            }
        }

        void levelINI(int level,Image bild)
        {
            if (level == 0)
            {
                this.Size = new System.Drawing.Size(600, 600);
                this.BackColor = Color.Black;
                g = new Graphics[9];
                pl = new Panel[9];
                for (int i = 0; i < 9; i++)
                {
                    pl[i] = new Panel();
                    pl[i].Size = new Size(200, 200);
                    pl[i].CreateControl();

                    this.Controls.Add(pl[i]);
                }
                for (int i = 0; i < 9; i++)
                   g[i] = pl[i].CreateGraphics();

               pl[0].Location = new Point(0, 0);
               pl[1].Location = new Point(200, 0);
               pl[2].Location = new Point(400, 0);
               pl[3].Location = new Point(0, 200);
               pl[4].Location = new Point(200, 200);
               pl[5].Location = new Point(400, 200);
               pl[6].Location = new Point(0, 400);
               pl[7].Location = new Point(200, 400);
               pl[8].Location = new Point(400, 400);
            }//Lvl1
        }

        void paintKomponents()
        {
            try
            {
               if (level == 0)
                    {
                        g[0].DrawImage(bild, 0, 0, 600, 600);
                        g[1].DrawImage(bild, -200, 0, 600, 600);
                        g[2].DrawImage(bild, -400, 0, 600, 600);
                        g[3].DrawImage(bild, 0, -200, 600, 600);
                        g[4].DrawImage(bild, -200, -200, 600, 600);
                        g[5].DrawImage(bild, -400, -200, 600, 600);
                        g[6].DrawImage(bild, 0, -400, 600, 600);
                        g[7].DrawImage(bild, -200, -400, 600, 600);
                        g[8].DrawImage(bild, -400, -400, 600, 600);
                    }

            }
            catch (Exception err) {}
        }

        void paintRepaint()
        {
            while (!abort)
            {
                
                Thread.Sleep(1000);
                paintKomponents();

            }
        }

        void game()
        {

            Thread.Sleep(2000);

            pl[8].Visible = false;
            for (int i = 0; i < 8; i++)
            {
                
            }
        }
    }
}

Wäre cool , wenn einer weiß , wie das jetzt genau geht.
Bitte postet keine Codesnips , sondern nur ganze kontexte.
 
Ich habs jetzt folgendermaßen umgeändert , klappt aber trotzdem nicht.

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace PuzzleBox
{
    public partial class Game : Form
    {
        PuzzleBox p;
        Image bild;
        int level;
        Graphics[] g;
        Panel[] pl;
        bool abort = false;
        Random r = new Random();
        
        public Game(PuzzleBox p,Image bild,int level)
        {
            InitializeComponent();
            this.p = p;
            this.bild = bild;
            this.level = level;
            abort = false;

            levelINI(this.level, this.bild);
            
            this.KeyPress += new KeyPressEventHandler(Game_KeyPress);
            this.MouseMove += new MouseEventHandler(Game_MouseMove);
            
            paintKomponents();

            Thread th = new Thread(paintRepaint);
            th.Start();

            backgroundWorker1.RunWorkerAsync();
        }

        void Game_MouseMove(object sender, MouseEventArgs e)
        {
           
        }

        void Game_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((int)e.KeyChar == (int)Keys.Escape)
            {
              abort = true;
              this.Hide();
              p.Show();
            }
        }

        void levelINI(int level,Image bild)
        {
            if (level == 0)
            {
                this.Size = new System.Drawing.Size(600, 600);
                this.BackColor = Color.Black;
                g = new Graphics[9];
                pl = new Panel[9];
                for (int i = 0; i < 9; i++)
                {
                    pl[i] = new Panel();
                    pl[i].Size = new Size(200, 200);
                    pl[i].CreateControl();

                    this.Controls.Add(pl[i]);
                }
                for (int i = 0; i < 9; i++)
                   g[i] = pl[i].CreateGraphics();

               pl[0].Location = new Point(0, 0);
               pl[1].Location = new Point(200, 0);
               pl[2].Location = new Point(400, 0);
               pl[3].Location = new Point(0, 200);
               pl[4].Location = new Point(200, 200);
               pl[5].Location = new Point(400, 200);
               pl[6].Location = new Point(0, 400);
               pl[7].Location = new Point(200, 400);
               pl[8].Location = new Point(400, 400);
            }//Lvl1
        }

        void paintKomponents()
        {
            try
            {
               if (level == 0)
                    {
                        g[0].DrawImage(bild, 0, 0, 600, 600);
                        g[1].DrawImage(bild, -200, 0, 600, 600);
                        g[2].DrawImage(bild, -400, 0, 600, 600);
                        g[3].DrawImage(bild, 0, -200, 600, 600);
                        g[4].DrawImage(bild, -200, -200, 600, 600);
                        g[5].DrawImage(bild, -400, -200, 600, 600);
                        g[6].DrawImage(bild, 0, -400, 600, 600);
                        g[7].DrawImage(bild, -200, -400, 600, 600);
                        g[8].DrawImage(bild, -400, -400, 600, 600);
                    }

            }
            catch (Exception err) {}
        }

        void paintRepaint()
        {
            while (!abort)
            {
                
                Thread.Sleep(1000);
                paintKomponents();

            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            
            Thread.Sleep(2000);
            //this.lblText.Visible = false;

            //pl[8].Visible = false;
            for (int i = 0; i < 8; i++)
            {

            }
        }
    }
}

Die ausgeklammerten Befehle im Backgroundworker sind wichtig und klappen nicht.
 
Zuletzt bearbeitet:
Ich sehe aber nicht das du den DoubleBuffer und Konsorten aktiviert hast. Bau mal folgendes bei dir rein:

Code:
   public Game(PuzzleBox p,Image bild,int level)
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);

            this.p = p;
            this.bild = bild;
            this.level = level;
            abort = false;

            levelINI(this.level, this.bild);
            
            this.KeyPress += new KeyPressEventHandler(Game_KeyPress);
            this.MouseMove += new MouseEventHandler(Game_MouseMove);
            
            paintKomponents();

            Thread th = new Thread(paintRepaint);
            th.Start();

            backgroundWorker1.RunWorkerAsync();
        }
 
"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement lblText erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."

Trotz Doppelpuffer (Übrigens ist dein Link deffekt)
 
Link ist korrigiert. Der Fehler kommt aber von deinem BackgroundWorker. Warum nun der Fehler genau ausgelöst wird, kann ich dir jetzt nicht sagen, hast eventuell den Thread falsch angesprochen? Erstell mal Testweiße einen "Release" und schau mal ob der Fehler auch vorkommt.
 
Link ist korrigiert. Der Fehler kommt aber von deinem BackgroundWorker. Warum nun der Fehler genau ausgelöst wird, kann ich dir jetzt nicht sagen, hast eventuell den Thread falsch angesprochen? Erstell mal Testweiße einen "Release" und schau mal ob der Fehler auch vorkommt.

Wenn ich die Operationen rauswerfe , bei denen ich auf das Panel zugreife klappt alles ohne Probleme
 
Zurück