Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Multithreading - mehrere Prozesse liefern ständig Daten, dass Button_Click nicht mehr reagiert
ManuelB
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

Multithreading - mehrere Prozesse liefern ständig Daten, dass Button_Click nicht mehr reagiert

beantworten | zitieren | melden

Hallo,

ich habe ein Projekt, welches über eine GUI mehrere Prozesse(zwischen einem und acht) startet.
Diese Prozesse überprüfen extern eine Hardware, indem sie Daten rausschicken und wieder empfangen. Die empfangenen Daten werden dann in je eine RichTextBox über einen asynchronen DataReceiveEvent und einen Delegaten geschrieben.
Bis dahin funktioniert alles wie gewollt.

Problematisch wird dann das Stoppen des Lese-Schreibe Testvorgangs bzw. dieser Prozesse.
Die GUI ist nicht eingefroren(d.h. Textbox wird ständig aktualisiert und wenn man mit der Maus über einen Button fährt, wird dieser auch hellblau unterlegt), aber der StopButton-Clickevent wird beim Clicken trotzdem nicht aufgerufen.
Ich vermute, dass die GUI mit dem Füllen der Textboxen einfach zu beschäftigt ist, um den ButtonClickEvent einzuleiten.
Gibt es hierfür einen Lösungsvorschlag?



Da ich noch ein Anfänger bin, freue ich mich über jeden Tipp und Verbesserungsvorschlag!

LG Manuel

Edit:



 private void btnProcessStart_Click(object sender, EventArgs e)
         {
         Thread ThreadModul1 = new Thread(new ParameterizedThreadStart(Modul1));
         if(!ThreadModul1.IsAlive)ThreadModul1.Start(ProzessFile);

         }

     public void Modul1(object ProzessFilename)
         {
             PModul1.StartInfo.FileName = ProzessFilename.ToString();
             PModul1.StartInfo.UseShellExecute = false;
             PModul1.StartInfo.RedirectStandardOutput = true;
             PModul1.StartInfo.RedirectStandardInput = true;
             PModul1.StartInfo.RedirectStandardError = true;
             PModul1.StartInfo.CreateNoWindow = true;
             PModul1.Start();

             PModul1.OutputDataReceived += new DataReceivedEventHandler((s, e) => { SetText("\r\n" + e.Data, 1); });
             PModul1.ErrorDataReceived += new DataReceivedEventHandler((s, e) => { SetText("\r\n" + e.Data, 1); });

             PModul1.BeginOutputReadLine();
             PModul1.BeginErrorReadLine();

         }



         private void SetText(string TextLine, Int16 ID)
         {
             if(ID == 1)
             {
                 AddTextDelegate del = new AddTextDelegate(AddText);
                 Invoke(del, ListModul1, TextLine, Color.Black);
             }
if(ID == 2)
             {
                 //usw            }


         }


         delegate void AddTextDelegate(RichTextBox rtb, string txt, Color col);

         private void AddText(RichTextBox rtb, string txt, Color col)
         {
             try
             {
                 int pos = rtb.TextLength;
                 rtb.AppendText(txt);
                 rtb.Select(pos, txt.Length);
                 rtb.Select();
                 rtb.SelectionColor = col;
                 rtb.SelectionStart = rtb.Text.Length;
                 rtb.ScrollToCaret();
             }
             catch { }//MessageBox.Show("Error at AddText to List"); }
         } 
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ManuelB am .
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.779
Herkunft: Waidring

beantworten | zitieren | melden

Hallo ManuelB,

mehr als den Text aus deiner Frage wissen wir nicht, daher kann auch keine genaue Antwort gegeben werden. Aber schau dir [Artikel] Debugger: Wie verwende ich den von Visual Studio? an, damit kannst du vllt. die Ursache lokalisieren.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.955

beantworten | zitieren | melden

Sieht für mich so aus das da zwar mit Threads gearbeitet wird, aber dann doch alles in den Gui Thread delegiert wird.

Siehe "Achtung: GUI-Zugriffe nur aus dem GUI-Thread" und "Achtung: Die Falle" in
[FAQ] Warum blockiert mein GUI?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von FZelle am .
private Nachricht | Beiträge des Benutzers
ManuelB
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Hallo,

danke für die schnellen Antworten.

Ich werde mir die von euch verlinkten Artikel gleich mal durchlesen.

Vielen Dank im Voraus

Manuel
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ManuelB am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.908
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Wenn du nur einen Thread hast, solltest du ggf. direkt auf den BackgroundWorker umstellen.
Ansonsten scheint deine GUI zu blockieren, was meistens daran liegt das du deine Verarbeitungen nicht im Kontext des ausgelagerten sondern im GUI Thread machst.

Eine Umstellung auf den BackgroundWorker scheint auf den ersten Blick sinnvoller zu sein.
Du musst dann eben nur Invoke aufrufen, wenn du die Controls der GUI aufrufen willst.
Aber dazu gibt es genug Anleitungen im Forum und Googel + den geposteten Artikel zu dem Thema blockierende GUI.

Nachtrag:
@ManuelB
Es wäre hilfreicher, wenn du nicht den gesamten Code doppelt postet.
Editiere dafür bitte deinen ersten Post ganz oben.

T-Virus
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.500

beantworten | zitieren | melden

Bitte keine Codes aus vergangenen Beiträgen verändern[/u], wenn sich darauf Beiträge beziehen könnten.
Ansonsten können manche Antworten nicht mehr nachvollzogen werden!! Dann lieber verändert doppelt posten (den relevanten Teil).
private Nachricht | Beiträge des Benutzers
weismat
myCSharp.de - Member



Dabei seit:
Beiträge: 872
Herkunft: Frankfurt am Main

beantworten | zitieren | melden

Ich würde an Deiner Stelle Deine Updates nur alle x ms im Block verarbeiten.
Eine Möglichkeit wäre es, eine Blocking Collection zu benutzen.
DataReceived schreibt in die Blocking Collection und ein eigener Update-Thread fast alle Änderungen in einem Schritt zusammen und ruft dann einmal für x ms das Invoke auf.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.500

beantworten | zitieren | melden

Und genau das ist zB in TPL Pipelines sehr gut beschrieben.
Sowas ist auch viel leichter umzusetzen, zu warten und zu skalieren.

Man sollte auch eher Tasks nutzen - sofern möglich - da sie sowohl für die Anwendung wie auch drum herum einfacher zu handlen und zu skalieren sind als Threads.
private Nachricht | Beiträge des Benutzers
ManuelB
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Vielen Dank an alle!

Eure Tipps haben mir wirklich sehr geholfen.

Ich habe mich nun für eine geblockte Ausgabe alle x ms entschieden und es klappt!!

LG Manuel
private Nachricht | Beiträge des Benutzers