• 0
Melde dich an, um diesem Inhalt zu folgen  
Folgen diesem Inhalt 0

C# Multi-Threading gebraucht?

Frage

Moinsen,

ich kam heute durch eine Anforderung auf eine seltsame Frage die vielleicht jemand beantworten kann:

Wenn ich ein Programm mit GUI habe, das einen Timer im Hintergrund hat der natürlich läuft und alle paar Sekunden eine Aktion ausführt, aber gleichzeitig Buttons habe die bei einem Klick ebenfalls Dinge ausführen brauche ich ja anscheinend kein Multi-Threading. Woher weiß ich denn wann ich Multi-Threading brauche und wann nicht? Was passiert denn genau wenn mein Code in einer Timer-Schleife ist und ich aber einen Button klicke der ein Ereignis auslöst? Wird das ancheinander verarbeitet? Gleichzeitig?

 

Grüße

Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

5 Antworten auf diese Frage

  • -1
46 minutes ago, Tician said:

Wenn ich ein Programm mit GUI habe, das einen Timer im Hintergrund hat der natürlich läuft und alle paar Sekunden eine Aktion ausführt, aber gleichzeitig Buttons habe die bei einem Klick ebenfalls Dinge ausführen brauche ich ja anscheinend kein Multi-Threading

Das liegt daran, dass in einem Betriebssystem sogenannte Scheduling Algorithmen dafür sorgen, dass jedem Prozess immer eine bestimmte Anzahl Rechenzeit zugewiesen wird, wenn die abgelaufen ist, bekommt der nächste Prozess seine Rechenzeit. Das passiert bei heutigen Prozessoren so schnell, dass dadurch eine Art "Pseudo Parallelität" erzeugt wird, bei dem der Benutzer den Eindruck hat, viele Dinge würden parallel laufen, was aber oft gar nicht der Fall ist. Beispiel: Du spielst ein Computerspiel und hörst gleichzeitig Musik. In wirklichkeit laufen diese Dinge oft gar nicht parallel ab, sondern im Wechsel - und das passiert so schnell, dass du weder eine Unterbrechnung im Spiel noch bei der Musik wahrnimmst. Wenn man darüber nachdenkt, schon Wahnsinn :) ...

46 minutes ago, Tician said:

Woher weiß ich denn wann ich Multi-Threading brauche und wann nicht?

Ich sag es mal so: Wenn du es brauchst, dann weißt zu dem Zeitpunkt auch, dass du es brauchst, z. B. wenn Workflows oder so wirklich unabhängig voneinander sind und du merkst dass die Rechenzeit anfängt enorm die Knie zu gehen. Gerade Anfängern die Mutli-Threading "erzwingen" wollen ist oft nicht klar, ob es wirklich Sinn macht. Was dann schnell passiert ist, dass beispielsweise Berechnungen parallelisiert werden, intern besteht aber zwischen den Berechnungen Abhängigkeiten und dann fangen die Prozesse an, gegenseitig auf sich zu warten. Dann ist Multithreading mehr oder weniger für die Katz.

Quote

Was passiert denn genau wenn mein Code in einer Timer-Schleife ist und ich aber einen Button klicke der ein Ereignis auslöst? Wird das ancheinander verarbeitet? Gleichzeitig?

Abwechselnd in einem vom Betriebssystem bestimmten Zeitintervall - und zwar so schnell, dass du den Eindruck hast, es wäre gleichzeitig. Wobei man richtigerweise sagen muss, es wechseln sich nicht nur diese beiden Prozesse ab, sondern wahrscheinlich dazwischen noch dutzend andere. z. B. Mauszeiger bewegen o.ä :) ...

 

Wenn dich sowas interessiert, kannst du ja mal einen Blick in den "Tanebaum" (Moderne Betriebssysteme von Andrew. S. Tanebaum) werfen. Der vermittelt die grundlegensten Prinzipien von Betriebssystemen. Total interessant.

bearbeitet von halcyon

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 3

Wobei man aber sagen muss, dass bei den heutigen Mehrkern-Prozessoren wirklich mehrere Dinge gleichzeitig abgearbeitet werden können.

Multi-Threading muss auch nicht immer was mit Geschwindigkeit zu tun haben. Wenn du in C# einen Timer startest, dann läuft der Timer im einem separaten Thread, da ansonsten die gesamte Anwendung durch den Timer blockiert wäre, da der Timer eine Endlosschleife ist. Ein anderes Beispiel ist eine Statusanzeige. Hier läuft die Logik in einem separaten Thread als die Statusanzeige und die Logik füttert die Anzeige mit Statusinformationen, die dann angezeigt werden.

Unter Android läuft sogar per Standard die komplette Benutzeroberfläche in einem separaten Thread, damit die Logik die Oberfläche nicht blockiert.

Du kannst ja gerne mal ein Test machen: Erstelle eine neue WinForms-Anwendung, packe dort einen Button rauf und im Click-Event schreibst du 

private void button1_Click(object sender, EventArgs e)
{
    while(true)
    { }
}

Nach dem klicken auf den Button kannst du dann das Fenster nicht mehr verschieben und auch nicht mehr mit dem Schließen-Button schließen, weil der Fokus nun auf der Endlosschleife liegt und die Oberfläche reagiert nicht mehr.

Jetzt verschieben wir die Endlosschleife in einen separaten Thread:

private void button1_Click(object sender, EventArgs e)
{
    new Thread(Execute).Start();
}

private void Execute()
{
    while(true)
    {}
}

Und siehe da: Selbst nach dem Klick auf den Button, kann man die Oberfläche verschieben und mit dem Schließen-Button schließen. Die Endlosschleife läuft nun in einem anderen Thread und blockiert nicht mehr die Oberfläche.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Woah das habe ich mal gut verstanden, vielen vielen Dank für die super Beispiele, das ist tatsächlich Wahnsinn was die heutigen PCs können! ^_^

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Programme laufen in einzelnen Threads. Wenn also die GUI im Mainthread läuft und rechenintensive Prozesse ausgeführt werden sollen, macht es Sinn, diese in einem Seperaten Thread laufen zu lassen, damit die GUI nicht "gesperrt" wird. Dazu ein Beispiel: Wenn man auf einen Button klickt und eine Datei gedownloaded wird, kann das durchaus, je nach Dateigröße und Internetgeschwindigkeit, eine Weile dauern. Das Programm wartet aber nach dem Klick auf den Button, bis die Datei gedownloaded ist und wird dann erst weiter abgearbietet. Somit kann es nicht mehr auf Benutzereingaben reagieren bzw. sogar abstürzen ("Das Programm reagiert nicht mehr").

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Also die praktische Erfahrung: Ich brauche Threading.

Mein Timer (scheint nicht automatisch in einen neuen Thread geschoben zu werden) blockiert alle 10 sekunden meine GUI. Bzw es blockiert sie nicht, geklickte Check-Boxen oder ein Text der in eine Textbox geschrieben wird werden 'nachgeholt'.

Aber ich schätze das kommt daher das ich einen Ping auf bestimmte Rechner absetze mit dem Timer und sich je nach Ergebnis das DataGridView in der GUI verändert. Und dann scheint eben nicht nur das DataGridView sondern die gesamte GUI mal für 2 Sekunden zu hängen, was dann doch etwas nervig ist.

Bringt mir dann Threading überhaupt etwas? Der Timer steht ja im Zusammenhang mit einem Element der GUI...

Noch etwas:

Wenn ich IN einem timer Thread.Sleep(x) benutze wird dann allgemein der Timer pausiert sodass ich x Sekunden Ruhe habe oder fängt der Timer-Durchlauf nach seinem eigenem Interval mit einem neuen Durchlauf an?

bearbeitet von Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
Gast
Du kommentierst als Gast. Wenn du bereits einen Account hast kannst du dich hier anmelden.
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoticons maximum are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

Melde dich an, um diesem Inhalt zu folgen  
Folgen diesem Inhalt 0