C# Progressbar und backgroundWorker mit dll verknüpfen

@Darlis

Kann man so machen. Ist dann halt wie ne drehende Sanduhr. Dann kann man sich all das ganze Threading sparen und der Code ist übersichtlich und einfach.
Halte ich für ne Quick and Dirty Lösung. Ich denke der TO sollte sich mit dem Thema Threading befassen. Es macht, wenn man es begriffen hat, einfach auch Spaß es einzusetzen.
 
Threading muss er sowieso machen, sonst wird der Dispatcher-Thread blockiert.
Ich habe das so verstanden, dass es nicht weiß, welche Werte er an die ProgressBar geben soll (wann sind 100% erreicht?). Daher mein Ansatz.
 
Ich versteh es leider nicht, Diese ganzen Beispiele welche man via Google findet verwirren nur noch mehr.
Bin -mal wieder- auf der msdn Seite und habe direkt eine Frage.

Code:
        private void startAsyncButton_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy != true)
            {
                // Start the asynchronous operation.
                backgroundWorker1.RunWorkerAsync();
            }
        }

dort wird der Worker via ButtonClick in der Form gestartet.
Ich habe aber keinen Button und keine Form wo der Worker gestartet wird sondern eine dll in der ein Event getriggert wird.
Soll ich nun den Namespace in die dll integrieren damit ich dort RunWorkerAsync aufrufen kann?

Ich finde einfach kein Beispiel wo der Worker NICHT in der Form via Button gestartet wird.
 
Zuletzt bearbeitet:
Es ist doch völlig Latte wie der BackgroundWorker aufgerufen wird. Wenn du ein Event in deiner dll hast (was nebenbei gesagt eine absurde BEschreibung ist, weil im Optimalfall egal ist ob du den Code in einer DLL hast oder im gleichen Programm) dann musst du in deinem GUI Code einen EventListener auf das Event setzen. Wenn jetzt der EventListener ein Event empfängt führst du eben "backgroundWorker1.RunWorkerAsync();" aus.

Generell würde ich aber in Erwägung ziehen das anders aufzuziehen. Nämlich das du in deinem Code für wo jetzt dein Event her kommt einfach ein Event für Status Updates (z.B. der Progress) hinzufügst. Dann ein EventHandler auf das Event und fertig.
 
Also ich habe nun einfach mein bestehendes Event erweitert. Auch wenn der Begriff dll unglücklich ist, so dient er lediglich meiner persönlich Semantik. Sonst verwirre ich mich nur noch mehr :D

Eventklasse:
Code:
 public class Event
    {
        public event EventHandler<DataEvent> MSRDataEvent;


        public void changevalue(int i)
        {
            if (ProgressUpdate != null)
            {
                ProgressUpdate(this, new DataEvent { Progress = i });
            }

        }
...

DataKlasse:

Code:
public class Data : EventArgs
    {
        public byte[] Data { get; set; }
        public string datastring1 { get; set; }
      
        public int Progress { get; set; }

        public string PictureFile { get; set; }
 
    }

Aufruf des Events in meiner Klasse (hier wird alles berechnet)

Code:
 private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //bwEvent.changevalue(10);
                
                string indata = "";
                
                SerialPort sp = (SerialPort)sender;
                indata = sp.ReadExisting();

                if (indata.Length != 0)
                {
                    if ((indata.Length == 979) && ((indata[0] == '797') || (indata[0] == 979')))
                    {
                     .....

                        
                    }
                    receiveEvent2.changevalue(95);
                        receiveEvent2.Received(PictureFile);
                        //Thread.Sleep(3000);
                    }
                
            }

Meine FormKlasse

Code:
public partial class Form1 : Form
    {
       
        Initialisierung init = new Initialisierung();
        On dataTest = new on();
             

        public delegate void MDelegate(string buffer, DataEvent e);
      

        

        public Form1()
        {

            InitializeComponent();  

            backgroundWorker1.WorkerReportsProgress = true;
            
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
           
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            
        }

        private void t1_OnProgressUpdate(int value)
        {
            // Its another thread so invoke back to UI thread
            base.Invoke((Action)delegate
            {
                label1.Text += Convert.ToString(value);
            });
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {

            var worker = sender as BackgroundWorker;         
               
            for (int i = 0; i <= 100; i++)
            {
               
                // Report progress to 'UI' thread
                backgroundWorker1.ReportProgress(i);
                // Simulate long task
                System.Threading.Thread.Sleep(100);
            }       
            e.Cancel = true;
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            
            change_PGBar(e.ProgressPercentage);
        }

        delegate void pghelper(int ProgressPercentage);

        void change_PGBar(int ProgressPercentage) //ich geh jetzt mal von int aus
        {
            if (InvokeRequired)
            {                
                pghelper del = new pghelper(change_PGBar);
                this.Invoke(del, ProgressPercentage); //ich glaube so oder so ähnlich ist die Syntax hier
            }
            else
            {
                progressBar1.Value = ProgressPercentage;
            }
        }

private void button1_Click(object sender, EventArgs e)
        {
                        
            dataTest.MEvent += new EventHandler<DataEvent>(this.Data);
               

        }

        private void RunWorker(object sender, DataEvent e)
        {
            backgroundWorker1.RunWorkerAsync();
            t1_OnProgressUpdate(e.Progress);
            
        }

        private void ReceivedData2(object sender, DataEvent e)
        {
                          
            pictureBox1.ImageLocation = "";
            this.BeginInvoke(new RFIDDelegate(this.DataRec2), e);            

        }

         public void DataRec2(DataEvent e)
        {
            if (e.PictureFile != "")
            {
                pictureBox1.ImageLocation = e.PictureFile;
                pictureBox1.Load();

            }    
        }

Also zumindest startet die Progressbar sobald Daten über den Port gehen.
Hab den restlichen Worker noch nicht angepasst und die Bar läuft einfach durch..

Ist dieser Ansatz denn nun richtig? Oder wird dies so nicht funktionieren?

PS:

Kann ich anstelle von int Werten nicht ein bool übergeben? True = RunWorkerAsync und false = CancelAsync(); ?
 
Zuletzt bearbeitet:
-Rayz- schrieb:
Auch wenn der Begriff dll unglücklich ist, so dient er lediglich meiner persönlich Semantik. Sonst verwirre ich mich nur noch mehr :D
Dann verwende diese Begriffe auch bitte nur persönlich und nicht, wenn du öffentlich eine Problemstellung beschreibst, dann bist nämlich nicht nur du verwirrt.

Die ProgressBar hast du etwas verüberkompliziert. Ein Backgroundworker ist ebenso nicht nötig. So wie ich das verstehe, läuft dein COM-Listener bereits in einem separaten Thread und spRFID_DataReceived vermutlich ebenso. Sollte das nicht der Fall sein, dann (und nur dann) muss eben diese Methode in den Backgroundworker, nicht die ProgressBar-Aktualisierung.

Deine RFID-Klasse hat schon ein Event ProgressUpdate, dass du auch sendest und in deiner Form schon empfängst. Du musst eigentlich nur noch den Status der ProgressBar entsprechend ändern (ggf. Thread wechseln). So wie es aussieht, startest du aber mit jedem Update den Backgroundworker? Ich glaube nicht, dass das Event dafür gedacht ist.

-Rayz- schrieb:
Kann ich anstelle von int Werten nicht ein bool übergeben? True = RunWorkerAsync und false = CancelAsync(); ?
Geht es um t1_OnProgressUpdate? Was ist t1?
Sprechende Namen wären übrigens sehr hilfreich.
 
dataTest ist ein Objekt der Klasse OnEvent.

Form Klasse:
Code:
        Initialisierung init = new Initialisierung();
        OnEvent dataTest = new Onevent();
             

        public delegate void MDelegate(string buffer, Event e);
        public delegate void RDelegate(Event e);
        public delegate void WorkerEvent(int Progress, Event e);

Event Klasse:

Code:
 public class Event
    {
        public event EventHandler<Event> DataEvent;
        public event EventHandler<Event> Event;
        public event EventHandler<Event> ProgressUpdate;

        public void Received(string data)
        {
            try
            {
                if (Event != null)
                {
                    Event(this, new DataEvent{PictureFile = data});
                   
                }

            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        public void changevalue(int i)
        {
            if (ProgressUpdate != null)
            {
                ProgressUpdate(this, new DataEvent { Progress = i });
            }

        }


Mit dem Button spring ich dann in die Klasse Initialisierung:

Code:
public class Initialisierung
    {     

        private int serialNumber = 0;      
       ...
                
        public void start(Event dataEvent)
        {
            serialNumber = 1;
            settings.startSettings();             
            
            switch (serialNumber)
            {
               ....
                    break;
            }
        }

Hier reiche ich das Event an meineKlasse weiter und weise es zu:

Code:
public class 
    {
SerialPort Port = new SerialPort();
        OnDataEvent receiveEvent2;


 public string start(OnDataEvent dataEvent)
        {
                          
                // Eventklasse erhält das gesetzte Event
                receiveEvent2 = dataEvent;

....
                port.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
               Port.Open()
}

Dann springe ich ja in meine sp_DataReceived MEthode, Berechne, und gebe die Daten an die Form zurück:

Code:
 MEthode: sp_DataReceived
                    receiveEvent2.changevalue(100);
                        receiveEvent2.Received(PictureFile);


// Form Klasse

private void ReceivedData2(object sender, DataEvent e)
        {
                          
            pictureBox1.ImageLocation = "";
            this.BeginInvoke(new Delegate(this.DataRec2), e);            

        }
        public void DataRec2(DataEvent e)
        {
            if (e.PictureFile != "")
            {
                pictureBox1.ImageLocation = e.PictureFile;
                pictureBox1.Load();

            }            
        }

Es werden doch nur die letzten beiden Methoden ReceivedData2 und DataRec2 in einem anderen Thread durch BeginInvoke ausgeführt oder nicht..? Also brauch ich doch den Backgroundworker..

PS: Namensgebung wird noch geändert.
 
Zuletzt bearbeitet:
Das einzig neue an deinem Post ist, dass du SerialPort verwendest. MSDN zu der DataReceived-Methode:
Das DataReceived-Ereignis wird in einem sekundären Thread ausgelöst, wenn Daten vom SerialPort-Objekt empfangen werden. Da dieses Ereignis in einem sekundären Thread und nicht im Hauptthread ausgelöst wird, kann der Versuch, Elemente wie UI-Elemente im Hauptthread zu ändern, eine Threadausnahme auslösen. Falls es erforderlich ist, Elemente im Haupt-Form oder im Haupt-Control zu ändern, senden Sie Änderungsanforderungen mithilfe von Invoke zurück, der den Vorgang dann auf dem richtigen Thread ausführt

Deine Behandlung des ReceivedData Events in der Form ist also korrekt und ich sehe nach wie vor keinen Sinn hier einen BackgroundWorker zu nutzen. Wozu auch? Was soll in dem BackgroundWorker deiner Meinung nach passieren? Du musst lediglich in der Form das ProgressUpdate-Event korrekt behandeln. Also so, wie du es mit dem ReceivedData-Event machst.
 
Gibt ja auch nichts neues. Wollte nur versuchen den Ablauf "ordentlich" aufzuzeigen um eventuelle Fehler zu vermeiden.
Ich dachte ich brauche den Backgroundworker deswegen, weil die Progressbar im Hintergrund/anderen Thread ausgeführt wird /werden muss.
Dann versuch ich es mal ohne.
 
Nein, die PogressBar muss nicht "ausgeführt" werden. Diese ist genau so ein GUI-Element wie PictureBox. Du musst diese lediglich in einem separaten Thread "befüllen", wenn du nicht willst, dass die GUI einfriert.
 
Und eben diesen separaten Thread dachte ich macht der Backgroundworker.
Ergänzung ()

So es geht weiter:

Wenn das Event getriggert wird geht es in folgende Methode:
Code:
Event:

        private void button1_Click(object sender, EventArgs e)
        {
            
                        
            dataTest.Event += new EventHandler<Event>(this.ReceivedData2);
            dataTest.Data += new EventHandler<Event>(this.ReceivedData);
            dataTest.ProgressUpdate += new EventHandler<Event>(this.StartWorker);
            
            init.start(dataTest);         

        }

        public void StartWorker(object sender, DataEvent e)
        {
            progress = e.Progress;
            if (e.Progress != 0)
            {
                if (backgroundWorker1.IsBusy == true)
                {
                    backgroundWorker1.CancelAsync();
                }
                else
                {
                    backgroundWorker1.RunWorkerAsync();
                }                    
            }
            else
            {
                if (backgroundWorker1.WorkerSupportsCancellation == true)
                {
                    backgroundWorker1.CancelAsync();
                }                    
            }            
        }

Und hier der Rest aus der Form Klasse:

Code:
private void t1_OnProgressUpdate(int value)
        {
            // Its another thread so invoke back to UI thread
            base.Invoke((Action)delegate
            {
                label1.Text += Convert.ToString(value);
                backgroundWorker1.ReportProgress(value);
            });
        }

        delegate void texthel(int text);
        private void labeltext(int text)
        {
            if (InvokeRequired)
            {
                texthel mytext = new texthel(labeltext);
                this.Invoke(mytext, text);
            }
            else
            {
                label1.Text = text.ToString();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            progressBar1.Maximum = 100;
            progressBar1.Step = 1;
            var worker = sender as BackgroundWorker;
            
                
            if (worker.CancellationPending == true)              
            {                   
                e.Cancel = true;                   
                return;                               
            }                
            else                
            {                   
                if (worker.WorkerReportsProgress)                   
                {     
                    labeltext(progress);                      
                    worker.ReportProgress(progress);                     
                }                
            }            

            this.backgroundWorker1.CancelAsync();          
      
            e.Cancel = true;
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            
            change_PGBar(e.ProgressPercentage);
            
        }

        delegate void pghelper(int ProgressPercentage);

        void change_PGBar(int ProgressPercentage) //ich geh jetzt mal von int aus
        {
            if (InvokeRequired)
            {                
                pghelper del = new pghelper(change_PGBar);
                this.Invoke(del, ProgressPercentage); //ich glaube so oder so ähnlich ist die Syntax hier
            }
            else
            {
                progressBar1.Value = ProgressPercentage;
                
            }      
        }

Hier meine Änderungen

Code:
 private async void ProgressValue()
        {
            await loadProgressValue();
        }

        private async Task loadProgressValue()
        {
           int i = 0;
           int counter = 0;
           await Task.Run(() =>
               {
                   while (taskvalue != false)
                   {
                       Thread.Sleep(30);
                       i++;
                       if (i >= 100)
                       {
                           i = 0;
                           counter++;
                           if (counter > 4)
                           {
                               taskvalue = false;
                           }
                       }
                       receiveEvent2.changevalue(i);
                   }
               }            
               
               );
        }
        
        private void sp_Received(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                
                taskvalue = true;
                string indata = "";
                
                SerialPort sp = (SerialPort)sender;
                indata = sp.ReadExisting();

                if (indata.Length != 0)
                {
                    if ((indata.Length == 88) && ((indata[0] == 'P') || (indata[0] == 'V')))
                    {
                        ProgressValue();
..................................................
                        taskvalue = false;
                        receiveEvent2.Received(PictureFile);
                        receiveEvent2.changevalue(100);
                    }

Das funktioniert sogar einigermaßen. Da ich nicht weiß, wo 100% sind, fängt der Ladebalken ab 100 von vorne an und geht maximal 5 mal durch bevor ich es abbreche.
Die erzeugten Werte lasse ich mir in meinem Label ausgeben ( zum überprüfen).

Und hier habe ich das Gefühl, dass die Werte im Label schneller aktualisiert werden als die Grafik in der Progressbar.
Auch ist der Wert "100" nicht immer die volle Progressbar... siehe Screenshot. Dabei steht das Maximum auf 100 und unabhängig von meiner async. Methode wird am Ende -eigentlich- eine 100 übermittelt..

Code:
                        taskvalue = false;
                        receiveEvent2.received(PictureFile);
                        receiveEvent2.changevalue(100);

ProgBar.JPG


Fehlt irgendeine Eigenschaft?
 
Zuletzt bearbeitet:
Du hast das Prinzip des BackgroundWorker immer noch nicht verstanden. Dieser wird für länger dauernde Aufgaben genutzt, um die GUI nicht zu blockieren. Du nutzt diesem aber um den Wert der ProgressBar genau ein Mal (oder auch kein Mal) zu ändern. BackgroundWorker.ProgressChanged läuft zudem auch schon im richtigen Thread und du benutzt trotzdem Invoke. Fehler sind auch reihenweise drin. Ich glaube komplizierter kann man den Code nicht mehr machen...

Wenn du wirklich nur erreichen willst, dass sich die ProgressBar bewegt, habe ich die Lösung (der Einzeiler) schon längst gepostet.
 
Zumindest sieht die Bar schöner aus mit dem Bgworker... aber dann könnt ich ja noch die Bar mit Hilfe eines Timers füllen.
Um aber nochmal zurück auf den Backgroundworker und der ProgressChanged Methode zu kommen.

Code:
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            
            change_PGBar(e.ProgressPercentage);
            
        }

        delegate void pghelper(int ProgressPercentage);

        void change_PGBar(int ProgressPercentage) //ich geh jetzt mal von int aus
        {
            if (InvokeRequired)
            {                
                pghelper del = new pghelper(change_PGBar);
                this.Invoke(del, ProgressPercentage); //ich glaube so oder so ähnlich ist die Syntax hier
            }
            else
            {
                progressBar1.Value = ProgressPercentage;
                
            }      
        }

Du meinst, es sei schon im richtigen Thread also müsste ja folgendes funktionieren:

Code:
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            //change_PGBar(e.ProgressPercentage);
            
        }

geht aber nicht...
{"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement progressBar1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."}

bestimmt hab ich es wieder falsch verstanden -_-

Deinen Einzeiler habe ich auch getestet. Frag nicht, wieso ich das nicht vorher schon gemacht habe aber dann hätte ich mir evtl. den ganzen Spaß mit dem Backgroundworker und asynchronen Threads vermasselt:D

Hier habe ich das Problem, dass wenn das Event zweimal getriggert wird, ich eine Fehlermeldung erhalte:

{"Auf das verworfene Objekt kann nicht zugegriffen werden.\r\nObjektname: \"Form1\"."}



Code:
        delegate void workerhelp(object sender, DataEvent e);

        public void StartWorker(object sender, DataEvent e)
        {
            if (InvokeRequired)
            {
                workerhelp whelp = new workerhelp(StartWorker);
                this.Invoke(whelp, sender, e);
            }
            else
            {
                progressBar1.Show();
                progressBar1.Style = ProgressBarStyle.Marquee;
            }

auch hier musste ich wieder Invoke nehmen sonst meckert er rum..
 
Zuletzt bearbeitet:
-Rayz- schrieb:
geht aber nicht...
{"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement progressBar1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."}
OK, "richtiger Thread" ist wohl nicht ganz richtig. Anscheinend wird der Thread genutzt, von dem aus RunWorkerAsync() aufgerufen wurde. Da dies i.d.R. der GUI-Thread ist, gibt es keine Probleme, bei dir ist das aber nicht so. Daher bräuchtest du tatsächlich Invoke.

-Rayz- schrieb:
Hier habe ich das Problem, dass wenn das Event zweimal getriggert wird, ich eine Fehlermeldung erhalte:

{"Auf das verworfene Objekt kann nicht zugegriffen werden.\r\nObjektname: \"Form1\"."}
Klar musst du Invoke nutzen, da du hier in der selben Situation bist, wie mit der PictureBox: Du befindest dich zu dem Zeitpunkt in einem von SerialPort erzeugen separaten Thread. Warum die Fehlermeldung kommt, kann ich aber nicht sagen.

Da du jetzt keinen BackgroundWoker mehr nutzt, räum' das Projekt mal etwas auf. Diese Zeile hier:
Code:
dataTest.ProgressUpdate += new EventHandler<DataEvent>(this.StartWorker);
suggeriert, dass mit jedem Fortschritt (egal welcher) ein BackgroundWorker gestartet wird.
 
So, mal etwas aufgeräumt.

Also hier starte ich wieder die Bar.


Code:
 private void sp_Received(object sender, SerialDataReceivedEventArgs e)
        {
            
                string indata = "";
                
                SerialPort sp = (SerialPort)sender;
                indata = sp.ReadExisting();
                
                if (indata.Length != 0)
                {
                    if ((indata.Length == 88) && ((indata[0] == 'P') || (indata[0] == 'V')))
                    {
                                                
                        receiveEvent2.changevalue(1);
                       ....................
                        receiveEvent2.changevalue(0);
                        receiveEvent2.Received(PictureFile);                      
                        
                    }
                        
                    }     
        }

Dann meine Form:


Code:
 private void button1_Click(object sender, EventArgs e)
        {
            
                        
            dataTest.DataEvent += new EventHandler<Event>(this.ReceivedData2);
            dataTest.Data += new EventHandler<Event>(this.ReceivedData);
            dataTest.ProgressUpdate += new EventHandler<Event>(this.StartProgressbar);
            
            init.start(dataTest);         

        }


        delegate void barhelp(object sender, Event e);

        public void StartProgressbar(object sender, Event e)
        {
            if (InvokeRequired)
            {
                barhelp whelp = new barhelp(StartProgressbar);
                this.Invoke(whelp, sender, e);                
            }
            else
            {

                if (e.Progress == 1)
                {                    
                    progressBar1.Style = ProgressBarStyle.Marquee;
                    progressBar1.MarqueeAnimationSpeed = 30;
                }

                else
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                }                
            }
}

Den Fehler konnte ich nicht reproduzieren aber ich glaube es lag evtl. daran, dass ich noch meine async. MEthode hatte und von dort aus ständig die Methode StartProgressbar aufgerufen hatte...:freak:

Ein "störendes" Problem hab ich nun allerdings noch.. hat zwar nichts mit Progressbar zutun aber bevor ich einen neuen Thread eröffne versuche ich es erstmal hier.

Ich erstelle ja in meiner Berechnung auch ein Bild (Picturefile)

Code:
....
if (File.Exists(PictureFile))
            {
                File.Delete(PictureFile);
            }
...

 PictureFile = @"e.jpg";
                        FileStream stream5 = new FileStream("e.jpg", FileMode.Create);
                        stream5.Write(biometricData, i, biometricLength - 4 - i);
                        stream5.Close();
                        stream5.Dispose();                        
                         
                        break;

Wenn ich nun wieder ein Event starte kommt folgendes:
+ $exception {"Der Prozess kann nicht auf die Datei \"D:\\c# Übungen\\DLLTest\\DLLTest\\bin\\Debug\\e.jpg\" zugreifen, da sie von einem anderen Prozess verwendet wird."} System.Exception {System.IO.IOException}

Ich dachte es könnte daran liegen, dass das Bild noch immer in meiner Form angezeigt wird also habe ich

pictureBox1.ImageLocation = "";

versucht. Ohne Erfolg.
Dann dachte ich, evtl. ist der stream noch offen aber close und dispose bringen mich auch nicht weiter. Ich könnte jedesmal das Bild umbenennen aber das finde ich sehr...unsauber.

Eine Idee welcher Prozess hier stören könnte?

PS: Mit der Porgressbar bin ich soweit zufrieden. Danke dafür :schluck:

PPS: der Name "receiveEvent2.changevalue(0);" wird noch geändert ! :)
 
Zuletzt bearbeitet:
Die ProgressBar sieht jetzt deutlich besser aus. :)

Kommt die Meldung beim Delete? Hast du das Bild zufällig in einem anderen Programm auf? ;)
Ich vermute mal, du hast beim Einlesen den Stream nicht geschlossen. Schau' dir mal die using-Klausel an, damit passiert dir so etwas nicht mehr.
 
Hab das delete mal entfernt.
Meinst du das mit dem using so?

Code:
                        PictureFile = @"e.jpg";
                        using (FileStream stream5 = new FileStream("e.jpg", FileMode.Create))
                        {
                            stream5.Write(biometricData, i, biometricLength - 4 - i);
                            stream5.Close();
                            stream5.Dispose();
                        }

Fehler kommt hier:
using (FileStream stream5 = new FileStream("e.jpg", FileMode.Create))

In der Form habe ich folgendes probiert:
Hier wie immer mein Event.

Code:
        private void button1_Click(object sender, EventArgs e)
        {
            
                        
            dataTest.DataEvent += new EventHandler<DataEvent>(this.ReceivedData2);
            dataTest.Event += new EventHandler<DataEvent>(this.ReceivedData);
            dataTest.Update += new EventHandler<DataEvent>(this.StartProgressbar);
            
            init.start(dataTest);         

        }

ReceivedData2:

Einmal mit BeginInvoke und einmal ohne.

Code:
private void ReceivedData2(object sender, Data e)
        {
            pictureBox1.ImageLocation = "";
            if (e.PictureFile != "")
            {
                pictureBox1.ImageLocation = e.PictureFile;
                pictureBox1.Load();

            }  
            
            //this.BeginInvoke(new Delegate(this.DataRec2), e);            

        }

Mit BeginInoke geht es dann hier weiter:

 public void DataRec2(DataEvent e)
        {
            
            if (e.PictureFile != "")
            {
                pictureBox1.ImageLocation = e.PictureFile;
                pictureBox1.Load();
               
            }        

        }

Hat alles nicht funktioniert.. :(
 
Zuletzt bearbeitet:
Nun geht es...
Code:
        private void ReceivedData2(object sender, DataEvent e)
        {     
            pictureBox1.Load(e.PictureFile);
            pictureBox1.Dispose();            
        }

Eigentlich war ich mir sicher, dass ich Dispose bereits probiert hatte... evtl. hat ja Dispose + Using das Problem gelöst..?
Nun gut damit hätte ich gerade keine weiteren Anliegen.

Ich danke euch vielmals für die Unterstützung!
 
Eigentlich war das Thema ja abgeschlossen, eigentlich...
Habe mich nochmal darangesetzt und nun eine für mich optimale Lösung gefunden.

Zuerst eine Methode welche in der Form aufgerufen werden kann.
Code:
        public void setProgressbar(bool Progress)
        {
            if (Progress == true)
            {
                backgroundworker.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundworker.backgroundWorker1_DoWork);
                backgroundworker.backgroundWorker1.WorkerReportsProgress = true;
                backgroundworker.backgroundWorker1.WorkerSupportsCancellation = true;
            }
            else
            {
                backgroundworker.backgroundWorker1.DoWork -= new DoWorkEventHandler(backgroundworker.backgroundWorker1_DoWork);
            }
        }

In der Form selber erzeugt man ein Event.

Code:
events.ProgressbarEvent += new EventHandler<Data>(this.yourProgressbar);
start(events);

Diesem Event weise ich dann meinen Backgroundworker zu.
Code:
public void initialization(Event data)
        {
        ....           
           ....
                    Port.startPort(Port, dataE);
                  ....
            }
        }

        public static void startPKTPort(string PKTPortName,OnDataEvent dataEvent)
        {
           backgroundworker._bgwEvent = dataEvent;
         }



Nun wird die Methode vom Backgroundworker aufgerufen:

Code:
public static void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            backgroundWorker1 = sender as BackgroundWorker;

            while (true)
            {
                for (int i = 1; i <= 100; i++)
                {
                    if (backgroundWorker1.CancellationPending == true)
                    {
                        _bgwEvent.Progressbar(0);  
                        e.Cancel = true;
                        return;
                    }
                    else
                    {
                        // Perform a time consuming operation and report progress.
                        if (backgroundWorker1.WorkerReportsProgress)
                        {
                            System.Threading.Thread.Sleep(50);
                            _bgwEvent.Progressbar(i);  
                            
                        }
                    }
                }                
            }
        }

In dieser Methode wird dann immer der aktuelle Wert an das Event weitergegeben und an die Form weitergeleitet:

Code:
 public int Progressbar { get; set; }


        public void Progressbar(int b)
        {
            if (ProgressbarEvent != null)
            {
                ProgressbarEvent(this, new Event { Progressbar = b });
            }

        }

Sobald keine Daten mehr anliegen oder ein Fehler auftaucht, wird die Progressbar beendet und in der Methode für die Progressbar auf 0 gesetzt:

Code:
            if (backgroundworker.CancellationPending == false)
                if (backgroundworker.WorkerSupportsCancellation == true)
                    backgroundworker.CancelAsync();


So das war es schon :)
 
Zuletzt bearbeitet:
Zurück
Oben