[C#] threading - Probleme

Hi Leute

mal eine Kurze Frage zum Thema Threading in C#.

wollte mit einer for-Schleife etwas wiederholen lassen und mit Hilfe von Thread.Sleep(1000) die ganze Sache etwas langsammer laufen lassen bzw. fur eine Zeit unterbrechen.

Code:
static void Main(string[] args)
        {
            short i;
            for (i = 1; i <= 10; i++)
            {
                Console.WriteLine("hallo");
                Thread.Sleep(1000);
            }
            Console.ReadKey();
        }
In einer Consolen Applikation das auch ohne Probleme ( siehe oben )

Wenn ich jetzt aber das ganze in einem Windows - Form einarbeite mit einer Listbox1 zur Ausgabe...

Code:
for (i = 1; i <= 10; i++)
    {
    try
        {
	lbox1.Items.Add("test");
	Thread.Sleep(1000);
        }
        catch 
        {
	MessageBox.Show("Fehler");
        }                
    }
passiert erst nichts und dann Alles auf einmal ( sprich als ob er den Befehl Sleep überspringt !? )

Könnt ihr mir Helfen, wo liegt da der Fehler? Oder muss ich es bei einem Windows - Form anders machen?

mfg Marc
 
Hallo,

Lösung für dein Problem ist Multithreading.

Ich würde es so machen:
Die Schleife in einem neuen Thread laufen lassen und über Delegates die neuen Werte an das Formular schicken.

Gruß Konstantin

[Für dieses Problem wahrscheinlich zu aufwendig.]
 
Man darf nicht von anderen Threads aus auf den Thread zugreifen, in dem das Control erstellt wurde.
Das Resultat was Du da gerade beobachtet hast nennt sich Deadlock.

Schau dir mal mein [thread=260455]Multi-Threading - Teil1: Einführung - Tutorial[/thread] an.
Ein Beispielprogramm zum Threading in Windows Forms findest in diesem [post=1337449]AW: Probleme beim neuzeichnen von pictureBox - Post[/post].
Dort wird Dir veranschaulicht was Konstantin mit Delegates gemeint hat.
 
hier ist ein Beispiel:

- Es gibt eine Maske mit einem Button und einer Listbox

C#:
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 De.Tutorials.Training.MultiThreading1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //Der neue Thread
        Thread newThread;

        //Wird gestartet wenn auf einen Button auf der Maske geklickt wird
        private void button1_Click(object sender, EventArgs e)
        {
            newThread = new Thread(new ThreadStart(run));
            newThread.Start();
        }

        //Diese Methode wird in einem neuen Thread ausgeführt
        void run()
        {
            delAddToList delegateATL = new delAddToList(this.addToList);
            string tmp = "tutorials";
            for (int i = 0; i < 100; i++)
            {
                //Hier kann man jetzt den Tread bremsen
                //Thread.Sleep(1000);

                //führt die Methode addToList aus
                this.Invoke(delegateATL, new object[] { tmp });
            }



        }

        //Über das Delegate wird ein Aufruf der Methode addToList möglich
        delegate void delAddToList(string value);
        public void addToList(string value)
        {
            this.listBox1.Items.Add(value);
        }

    }
}


Gruß Konstantin
 
Danke für das sehr anschauliche Beispiel Konstantin. :)
Marc, das ist ein sehr rudimentäres Beispiel und sollte so in der Praxis nicht verwendet werden, da hier der Business-Layer mit dem Präsentations-Layer vermischt wird. Wie Du die Ebenen sauber und OOP gerecht trennen kannst, siehst in meinem Beispielprogramm.
 
Hallo!

ginge auch so:
C#:
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 De.Tutorials.Training.WinForms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStartCounter_Click(object sender, EventArgs e)
        {
            new Thread(delegate()
            {
                for (int i = 0; i < 1000; i++)
                {
                    Thread.Sleep(100);
                    lblCounterValue.Invoke(new UpdateCounterValue(delegate()
                    {
                        lblCounterValue.Text = "" + i;
                    });

                }
            })).Start();
        }

        delegate void UpdateCounterValue();

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Environment.Exit(0);
        }
    }
}

Gruß Tom
 
C#:
new Thread(new ThreadStart(delegate()
{
    for (int i = 0; i < 1000; i++)
    {
        Thread.Sleep(100);
        lblCounterValue.Invoke(new UpdateCounterValue(delegate()
        {
            lblCounterValue.Text = "" + i;
        }));

    }
})).Start();
Krass, ist das delegate() {} neu in .NET 2.0? So was hab ich noch nicht gesehen. Das muss ich heut abend zuhause gleich mal ausprobieren. ;-)
Wird aber langsam mal Zeit, dass ich hier auf Arbeit auch endlich mit dem VS2005 Arbeiten kann.
 
Ich danke Dir! Bin nocht leider noch nicht dazu gekommen, mir das neue Programmierhandbuch mal komplett durchzulesen. Jetzt werde ich für den 2. Teil meines Threading Tutorials wohl noch ein bisschen Grundlagenforschung betreiben müssen...
 
Hi,

so jetzt muss ich mich erst mal wieder dazu melden :p

Hatte nicht gedacht das so ein "banales" Problem ein solchen Rattenschwanz hinter sich herzieht ;) .

Werd mich jetzt wohl auch erstmal oder "nochmals" in meinen Büchern verstecken und mich tiefgründiger mit Threads beschäfftigen. Dennoch danke ich euch für eure Hilfe sowie Lösungsbeispielen.....

mfg MArc
 

Neue Beiträge

Zurück