Entwickler-Ecke

WinForms - Multithreading


TroubleBubble - Mi 24.11.10 21:02
Titel: Multithreading
Hallo zusammen, und schon wieder ein neuer Neuling, der nicht weiter weiß :)
Bei meinem Programm habe ich versucht, Multithreading zu implementieren, damit
ich, während meine for-Schleife die x-Variable ständig erhöht, noch andere
Aktionen ausführen kann, nur leider beginnt er gar nicht erst mit
"public void MyThreadstart()", ich hoffe ihr könnt mir weiterhelfen, hier mal
mein Code


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
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 WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        public int x,y,i;
        public double vx;
                    



        private void Form_KeyDown (object sender, KeyEventArgs e)
        {
            while (e.KeyCode == Keys.L)
            {
                Application.Exit();
            }

        }

       


        private void button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    
        
        private void button2_Click_1 (object sender, EventArgs e)
        {



        }

        public void MyThreadstart()
         {
             Graphics g;

             g = CreateGraphics();
            for (; ; )
            {


                vx += 1;
                if (vx >= 100)
                {
                    x += 1;
                    vx = 0;
                }
                g.DrawLine(Pens.Black, new Point(x + 100, y + 120), new Point(x + 150, y + 120));
                g.DrawLine(Pens.Black, new Point(x + 150, y + 120), new Point(x + 150, y + 170));
                g.DrawLine(Pens.Black, new Point(x + 150, y + 170), new Point(x + 100, y + 170));
                g.DrawLine(Pens.Black, new Point(x + 100, y + 170), new Point(x + 100, y + 120));
            }

            
        }


    }


Ralf Jansen - Mi 24.11.10 21:35

Wo startest du denn die MyThreadstart Methode als Thread?
Wie das geht steht z.B. in der Msdn Doku hier [http://msdn.microsoft.com/de-de/library/a9fyxz7d%28v=VS.100%29.aspx](mit Beispiel).


TroubleBubble - Mi 24.11.10 21:41

Oh, da hab ich wohl versehentlich zu viel gelöscht um den Code zu kürzen, hier noch mal der vollständige


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
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 WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        public int x,y,i;
        public double vx;
                    



        private void Form_KeyDown (object sender, KeyEventArgs e)
        {
            while (e.KeyCode == Keys.L)
            {
                Application.Exit();
            }

        }

        public void Main1(string[] args)
        {
            ThreadStart del;
            del = new ThreadStart(MyThreadstart);
            Thread myFirstThread = new Thread(del);


            // den zweiten Thread starten 
            myFirstThread.Start();
        }



        private void button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    
        
        private void button2_Click_1 (object sender, EventArgs e)
        {

        }

        public void MyThreadstart()
         {
             Graphics g;

             g = CreateGraphics();
            for (; ; )
            {


                vx += 1;
                if (vx >= 100)
                {
                    x += 1;
                    vx = 0;
                }
                g.DrawLine(Pens.Black, new Point(x + 100, y + 120), new Point(x + 150, y + 120));
                g.DrawLine(Pens.Black, new Point(x + 150, y + 120), new Point(x + 150, y + 170));
                g.DrawLine(Pens.Black, new Point(x + 150, y + 170), new Point(x + 100, y + 170));
                g.DrawLine(Pens.Black, new Point(x + 100, y + 170), new Point(x + 100, y + 120));
            }

            
        }


    }
}


Ralf Jansen - Mi 24.11.10 23:12

ok. Aber die Main1 Methode wird jetzt aber von irgend woher aufgerufen oder?

Die so aussehen zulassen wie eine Main Methode ohne das es eine Main Methode ist finde ich unglücklich.


TroubleBubble - Mi 24.11.10 23:37

Ah, die muss ich noch extra aufrufen lassen? Mir scheint, dass ich beim
Grundlagen anlesen nicht ganz aufgepasst habe, wäre es möglich, mir kurz
zu erklären, wo ich das deklarieren muss?


jaenicke - Do 25.11.10 04:21

user profile iconTroubleBubble hat folgendes geschrieben Zum zitierten Posting springen:
wäre es möglich, mir kurz zu erklären, wo ich das deklarieren muss?
Naja, du musst den Code eben da hinschreiben, wo er ausgeführt werden soll, zum Beispiel in einen Buttonklick. Die Methode kannst du dann auch StartCalculationThread oder so nennen und diese dann dort aufrufen.

Wenn der Thread direkt beim Programmstart gestartet werden soll, kannst du das im Ereignis Load des Formulars machen.


Th69 - Do 25.11.10 13:02

Sorry TroubleBubble, aber leider ist deine Herangehensweise an Multithreading ungünstig.

Nur der GUI-Thread darf auch GUI-Aktionen ausführen (d.h. in dem Nebenthread darfst du nicht auf die Form zeichnen! Und CreateGraphics() ist ganz böse!!! Zeichnen sollte man nur in dem Paint-Ereignis).

Mir scheint dir fehlen noch zu viele Grundlagen der GUI-Programmierung, um jetzt schon Multithreading einzusetzen. Als Alternative zu eigenen Threads gibt es auch den 'BackgroudWorker', der besser mit dem GUI-Thread interagiert.

Am besten, du liest dir mal folgende Beiträge aufmerksam durch:
[Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox) [http://www.mycsharp.de/wbb2/thread.php?threadid=21782]
[FAQ] Warum blockiert mein GUI? [http://www.mycsharp.de/wbb2/thread.php?threadid=27992]
[FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) [http://www.mycsharp.de/wbb2/thread.php?threadid=33113]