Laden...

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

Erstellt von ManuelB vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.443 Views
M
ManuelB Themenstarter:in
5 Beiträge seit 2015
vor 8 Jahren
Multithreading - mehrere Prozesse liefern ständig Daten, dass Button_Click nicht mehr reagiert

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"); }
         } 
6.911 Beiträge seit 2009
vor 8 Jahren

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!"

F
10.010 Beiträge seit 2004
vor 8 Jahren

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?

M
ManuelB Themenstarter:in
5 Beiträge seit 2015
vor 8 Jahren

Hallo,

danke für die schnellen Antworten.

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

Vielen Dank im Voraus

Manuel

T
2.219 Beiträge seit 2008
vor 8 Jahren

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

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.

16.807 Beiträge seit 2008
vor 8 Jahren

++:::

Ansonsten können manche Antworten nicht mehr nachvollzogen werden!! Dann lieber verändert doppelt posten (den relevanten Teil).

W
872 Beiträge seit 2005
vor 8 Jahren

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.

16.807 Beiträge seit 2008
vor 8 Jahren

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.

M
ManuelB Themenstarter:in
5 Beiträge seit 2015
vor 8 Jahren

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