[c#]backgroundWorker problem

Dshing

Lt. Commander
Registriert
Nov. 2007
Beiträge
1.436
Hi,
ich habe gerade ein Problem.
Ich habe einen backgroundWorker, in dem ich auf bestimmte Ereignisse warte (Temperaturen vom System), wenn diese nun eintreten soll ein anderer backgroundWorker gestartet werden, der 1.8s braucht bis er fertig ist und sich dann wieder beendet. Nun soll aber der erste backgroundWorker in einem kleineren Intervall als 1.8s arbeiten, daher bedarf es noch eines Kriteriums, das der zweite backgroundWorker erst nach frühestens 1.8s wieder gestartet wird.
Eigentlich sollte der Code das auch sicher stellen bin ich der Meinung, aber irgendwie bekomme ich immer die Fehlermeldung: "Dieser BackgroundWorker ist derzeit ausgelastet und kann nicht mehrere Aufgaben gleichzeitig ausführen." wenn der zweite backgroundWorker starten sollte.
Also wenn ich es manuell starte und min. 1.8s warte, dann klappt es auch, also scheint er in meinem Code mehrmals zu starten. Nur sehe ich nicht warum. Könnt ihr mir helfen?


Code:
 private void backgroundWorker3_DoWork_1(object sender, DoWorkEventArgs e)
        {
            
      while(1==1)
      {
      
            backgroundWorker3.ReportProgress(1);
            System.Threading.Thread.Sleep(100);
          
  }
        }
  private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
     
     
      
      b++;
      if (b == 60000)
      { 
        b = 10000;
      }

      label5.Text = everest("Value.TCC-1-1");
      label6.Text = everest("Value.TCC-1-2");
      label7.Text = everest("Value.TCC-1-3");
      label8.Text = everest("Value.TCC-1-4");
      label9.Text = everest("Value.TGPU1DIOD");
      label10.Text = everest("Value.TGPU1DIOM");
      label11.Text = everest("Value.TGPU1DIOS");
      label12.Text = everest("Value.TMOBO");

      if (a==0 && Convert.ToDouble(everest("Value.TCC-1-1")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-2")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-3")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-4")) >= 55
          || Convert.ToDouble(everest("Value.TGPU1DIOD")) >= 55 || Convert.ToDouble(everest("Value.TGPU1DIOM")) >= 60 || Convert.ToDouble(everest("Value.TGPU1DIOS")) >= 55)
      {
          a = 1;
          b = 0;
          label13.Text = "warm";
          backgroundWorker4.RunWorkerAsync();
                    
      }
      if (b==700 && Convert.ToDouble(everest("Value.TCC-1-1")) <= 37 && Convert.ToDouble(everest("Value.TCC-1-2")) <= 37 && Convert.ToDouble(everest("Value.TCC-1-3")) <= 37 && Convert.ToDouble(everest("Value.TCC-1-4")) <= 37
          && Convert.ToDouble(everest("Value.TGPU1DIOD")) <= 37 && Convert.ToDouble(everest("Value.TGPU1DIOM")) <= 44 && Convert.ToDouble(everest("Value.TGPU1DIOS")) <= 43)
      {
          serialPort1.Write(new byte[] { 0x21 }, 0, 1);
          a = 0;
          label13.Text = "kalt";
      }
  }

  private void backgroundWorker4_DoWork(object sender, DoWorkEventArgs e)
  {
      serialPort1.Write(new byte[] { 0x20 }, 0, 1);
      System.Threading.Thread.Sleep(100);
      serialPort1.Write(new byte[] { 0x13 }, 0, 1);
      System.Threading.Thread.Sleep(700);
      serialPort1.Write(new byte[] { 0x12 }, 0, 1);
      System.Threading.Thread.Sleep(1000);
      serialPort1.Write(new byte[] { 0x11 }, 0, 1);
      System.Threading.Thread.Sleep(100);
      serialPort1.Write(new byte[] { 0x10 }, 0, 1);
      backgroundWorker4.CancelAsync();
  }
a und b sind globale Variablen, die bisher aber nur in dem Abschnitt hier verwendet werden
 
Dein Ansatz ist imo grundlegend falsch.

Du kannst nicht davon ausgehen, dass der BackgroundWorker nach 1,8s fertig ist. Er kann theoretisch auch 5 Minuten (oder noch länger) brauchen, wenn das System dem Thread einfach keine CPU-Zeit zuteilt. Ein Thread wird nicht immer "am Stück" ausgeführt, sondern oft nur "häppchenweise", was bedeutet, dass dein zweiter Worker Thread evtl. mittendrin unterbrochen wird, damit ein anderer Thread CPU-Zeit bekommt.

Verlass dich also niemals auf irgendeine Zeitspanne um festzustellen ob ein Thread fertig abgearbeitet ist.
Wenn du prüfen willst, ob der BackgroundWorker fertig ist, prüf lieber die IsBusy Property, die ist genau dafür vorgesehen. ;)
 
Ok ich hab jetzt noch das Kriterium mit eingebaut. Jetzt sollte er doch nur den backgroundWorker starten können wenn er nicht schon läuft oder? Ich hab auch nur an der Stelle hier ein "backgroundWorker4.RunWorkerAsync();" eingebaut, also er kann nur hier gestartet werden.
Aber dennoch kommt die Fehlermeldung :mad:
Ich hab sogar noch ein label, das mit anzeigt ob er beschäftigt ist oder nicht und dass steht auf "nicht beschäftigt". Beim ersten mal funktioniert es auch nach dem starten des Programms, aber sobald die Werte ein zweites mal erreicht werden geht es schief obwohl er nicht beschäftigt ist.

Code:
if (a == 0 &&[B][COLOR="Red"] (this.backgroundWorker4.IsBusy == false)[/COLOR][/B] && Convert.ToDouble(everest("Value.TCC-1-1")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-2")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-3")) >= 55 || Convert.ToDouble(everest("Value.TCC-1-4")) >= 55
          || Convert.ToDouble(everest("Value.TGPU1DIOD")) >= 55 || Convert.ToDouble(everest("Value.TGPU1DIOM")) >= 60 || Convert.ToDouble(everest("Value.TGPU1DIOS")) >= 55)
      {
          a = 1;
          b = 0;
          label13.Text = "warm";
          backgroundWorker4.RunWorkerAsync();
                    
      }
 
Hi,

es gibt beim Backgroundworker auf das Event RunWorkerCompleted, das gefeuert wird, wenn der Thread abgeschlossen ist.

Du solltest dich nicht auf irgendwelche Berechnungen / Schätzungen verlassen. Setze ein Flag, wenn der zweite BGW das RunWorkerCompleted-Event wirft, erst wenn dieses gesetzt ist soll es möglich sein, einen neuen Thread zu starten.

VG,
Mad
 
@Dshing
In deiner if-Bedingung sind die Klammern falsch gesetzt/fehlen.
Sobald ein Sensorwert >55 ist wird versucht den Worker zu starten, egal ob der Worker noch arbeitet oder nicht.

Is nicht böse gemeint, aber ich glaub bevor du mit Threads rumhantierst solltest du dir erst mal die Grundlagen aneignen, denn dein Code ist ganz großer Käse.
 
Ahh ja das wars :) Danke!!! :D
Ich weiß wenn ich ordentlich alle Grundlagen wüsste, dann wär mir das vielleicht auch selber aufgefallen, aber wenn jeder von allem die Grundlagen beherrschte, dann wären Foren wie diese hier zu 99.9% überflüssig. Mal ganz zu schweigen von der Problematik wie man sich das ganze Wissen merken sollte.
Ich mache das ja nicht beruflich oder so. Ich will nur das ein oder andere basteln als Hobby, und dann immer erst die Grundlagen von allen zu lernen, bevor man mal anfängt die erste Idee auch um zusetzen dauert mir doch erheblich zulange.
Daher hoffe ich immer das es Leute wie euch gibt, die mir hin und wieder mal mit Rat zur Seite stehen :)
 
Dshing schrieb:
Ahh ja das wars :) Danke!!! :D
Ich weiß wenn ich ordentlich alle Grundlagen wüsste, dann wär mir das vielleicht auch selber aufgefallen, aber wenn jeder von allem die Grundlagen beherrschte, dann wären Foren wie diese hier zu 99.9% überflüssig. Mal ganz zu schweigen von der Problematik wie man sich das ganze Wissen merken sollte.
Ich mache das ja nicht beruflich oder so. Ich will nur das ein oder andere basteln als Hobby, und dann immer erst die Grundlagen von allen zu lernen, bevor man mal anfängt die erste Idee auch um zusetzen dauert mir doch erheblich zulange.
Daher hoffe ich immer das es Leute wie euch gibt, die mir hin und wieder mal mit Rat zur Seite stehen :)

Uhi, die Aussagen bringen Zündstoff mit sich. Mal sehen was passiert :)
 
Wenn jeder die ganzen Grundlagen beherrschen würde, stellt sich die Frage, wie man sich das merken soll, doch gar nicht mehr ... ;)
 
Zurück
Oben