Entwickler-Ecke

Sonstiges (.NET) - Eine Frage zur While Schleife


SharinganShuriken - Mo 27.08.12 16:41
Titel: Eine Frage zur While Schleife
Hallo liebe Community,

heute habe ich eine etwas ungewöhnliche Frage und zwar habe ich in meiner Form eine while Schleife:


C#-Quelltext
1:
2:
3:
4:
5:
while(this.created)
{
  Application.DoEvents();
  // Mach etwas
}


Wenn ich aber von meiner Form eine zweite Form starte, also



C#-Quelltext
1:
form2.ShowDialog();                    


Stopt die While Schleife bis ich den Dialog wieder geschlossen habe :(

Das selbe passiert auch wenn ich auf den Fensterrahmen des Programm klicke oder die größe der Form mit der Maustaste verändere :(

Gibt es da eine Möglichkeit oder eine andere Schleife (außer Timer, Timer ist zu langsam) womit die Schleife immer läuft egal ob ich jetzt eine zweite Form öffne oder die größe der Form verändere ???

Liebe Grüße
SharinganShuriken


Ralf Jansen - Mo 27.08.12 16:45

Wen du eine Form Modal anzeigst dann ist auch nur diese eine Form aktiv. Wenn deine anderen Formen weiterarbeiten sollen ist Modal also irgendwie das falsche für dich :gruebel:

Wenn du etwas brauchst das parallel noch was anderes macht mach einen Thread auf und führe deine Aufgabe darin aus. Aktualisieren einer Form ist dann aber auch nur möglich mit der gerade Modal angezeigten obersten Form.


SharinganShuriken - Mo 27.08.12 16:49

Hallo,

was ist Thread, ist das eine Schleife, wenn ja ist sie genauso schnell wie die while Schleife ?

Liebe Grüße
SharinganShuriken


Th69 - Mo 27.08.12 17:00

Hallo SharinganShuriken,

die Gegenfrage ist: warum benötigst du diese Schleife? Application.DoEvents() ist nur ein schlechter Hack, um die GUI aktiv zu halten. Wenn du parallele Aufgaben hast, so solltest du z.B. unter WinForms den Backgroundworker [http://msdn.microsoft.com/de-de/library/system.componentmodel.backgroundworker.aspx] benutzen. Alternativ eben die von Ralf angesprochenen Threads (bzw. ab .NET 4.0 Tasks) - und hierzu bitte ein bißchen Eigeninitiative, d.h. eine Suchmaschine deiner Wahl benutzen, wenn du Begriffe nicht kennst ;-).


SharinganShuriken - Mo 27.08.12 17:34

Hallo,

habe mal ein Tasks ausprobiert:


C#-Quelltext
1:
2:
3:
4:
            Task.Factory.StartNew(() =>
             {
                 this.Text = "";
             });


Bekomme aber wie beim Backgroundworker immer eine Fehlermeldung :( : Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

???

Liebe Grüße
SharinganShuriken


Ralf Jansen - Mo 27.08.12 18:06

Du darfst aus einen Thread nicht einfach auf visuelle Controls eines anderen Threads zugreifen. Den Aufruf musst du über Invoke [http://msdn.microsoft.com/de-de/library/zyzhdc6b%28v=vs.100%29.aspx] ausführen.


SharinganShuriken - Mo 27.08.12 18:25

Hallo,

habe es mal damit versucht:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.RunWorkerAsync();
        }
        int i = 0;
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Invoke(new MethodInvoker(
               delegate 
               {
                   while (this.Created)
                   {
                       Application.DoEvents();
                       this.Text = i++.ToString();
                   }
               }
               ));
        }


Jetzt stottert die Schleife auch noch und das Problem mit dem stopen der Schleife ist immer noch da :( ???

Gibts nicht ihrgendeine Möglichkeit eine Global While Schleife zu machen, die Schleife muss genauso schnell sein wie die while und halt immer und bis ich das Programm beende laufen ?


Palladin007 - Mo 27.08.12 18:28

Multithreading und Multithreading ist ein kompliziertes und schweres Feld, einfach drauf los zu basteln wird dir keinen Erfolg und eine ganze Menge Frust bringen.

Hier das Kapitel aus dem Buch, mit dem ich C# gelernt habe:

http://openbook.galileocomputing.de/visual_csharp_2010/visual_csharp_2010_11_001.htm#mjd93ae35731528c9cb9d0d6cfbd011600

Da ist das, finde ich, sehr gut erklärt.
Aber lies dir alles durch, auch wenn Multithreading bei Prozessoren mit mehreren Kernen überflüssig erscheint, denn die Kenntnisse kannst du dennoch gut nutzen.
Also brav von dem Überblick bis zu TPL lesen ;)


Zum Thema Backgroundworker:
Den habe ich selber noch nicht genutzt, aber ich rate einfach mal wild drauf los und vermute, der funktioniert ähnlich wie TPL oder Multithreading


SharinganShuriken - Mo 27.08.12 18:56

Hallo,

ich habe eine Software, wenn ich mit dieser Software eine SubForm aufmache, sieht es so aus als wäre diese mit Show anstatt ShowDialog geöffnet und das interessante ist dabei wenn ich in die MainForm klicke, verschwindet die SubForm garnicht sondern ist einfach nicht mehr selectiert (TopMost ist es nicht), wie kann ich denn so etwas einstellen bei einer SubForm, das würde mein Problem auch lösen :D ?

Liebe Grüße
SharinganShuriken


Palladin007 - Mo 27.08.12 19:21

Und nebenbei soll noch Daten-Austausch möglich sein?

Was du versuchen könntest, wäre die Übergabe mittels Events.
Wenn du im MainForm also Events fest legst, die im SubForm ausgelöst werden. In den Parametern kannst du dann (Ein Objekt einer Klasse mit der geläufigen Endung "EventArgs") entsprechende Informationen an das MainForm zurück geben, das dafür aber nicht auf das SubForm warten muss, also auch Show an Stelle von ShowDialog aus reicht.


Kha - Mo 27.08.12 20:02

user profile iconSharinganShuriken hat folgendes geschrieben Zum zitierten Posting springen:
das interessante ist dabei wenn ich in die MainForm klicke, verschwindet die SubForm garnicht sondern ist einfach nicht mehr selectiert (TopMost ist es nicht)
Du meinst wahrscheinlich Owner [http://msdn.microsoft.com/en-us/library/system.windows.forms.form.owner.aspx] (kannst du auch direkt Show übergeben).


SharinganShuriken - Mo 27.08.12 21:52

Kha du bist mein Held, ich liebe dich, 100000000000000000 mal Dank XD

Nein jetzt ernsthaft, mit owner hats super funktioniert :D

Als Beispiel:


C#-Quelltext
1:
2:
3:
Form2 form = new Form2();
form.owner = this;
form.Show();


Liebe Grüße
SharinganShuriken


Palladin007 - Mo 27.08.12 22:14

Oh Mann, da hätte ich auch drauf kommen können :D


So einfach und ich komme mit Events -.-


Aber schön, dass es jetzt funktioniert ^^