C# Multithreading

Hawkings

Erfahrenes Mitglied
Hi @ all...

Ich befasse mich im Moment mit Multithreading und würde es gerne etwas besser verstehen, jedoch sind bei mir immer noch einige Verständnisfragen da, die ich an einem Beispiel erklären will.

Das ich Multithreading benötige, um mein Programm sauber ablaufen zu lassen, habe ich an meinem letzten Programm gesehen.
Dort hatte ich eine Progressbar, eine Uhrzeit. Über einen Button wurde ein Netzlaufwerk zu einem PC verbunden und einige Dateien übertragen sowie nebenbei je nach Fortschritt die Progressbar einen weiteren Schritt machen. Soweit zur Theorie, die Uhr ging dann auch nicht :suspekt:

Klar, denn es ist ja ein Single-Threading momentan, es arbeitet nur die Übertragung ab, dann erst die Progressbar und dann die Uhr...oder hängt sich halt auf.
Die einzelnen Schritte werden nacheinander abgearbeitet, ich möchte aber, dass die Progressbar immer, wenn eine Datei übertragen wurde, einen Schritt weitermacht und die Uhr aktualisiert wird das die Übertragung ohne (merkbare) Unterbrechung läuft.

Hierfür brauche ich dann ja das Multithreading, den Hauptfred mit der Übertragung und 2 Nebenfreds für Uhr und Progressbaraktualisierung. Stimmt das soweit?!

Bei meiner Suche im :google: habe ich mir alles, was mit Mutlithreading zusammenhängt angeschaut :p und bin schließlich bei Galileo Computing hängengeblieben. Diese hatten ein gut erklärten #Bericht dazu.

Außerdem wie übergebe ich Parameter und empfange sie sowie gebe sie zurück?!
Ich arbeite ja in einem Formular, wie sieht das aus dann aus mit dem Hauptthread und den Nebenthreads?!

Danke im Vorraus, Hawkin
 
Zuletzt bearbeitet:
Hallo Hawkin,

zum einen hättest du die Möglichkeit einen neuen Thread zu starten und aus diesem
per Invoke den Progressbar zu aktualisieren; für die Uhr genauso.

Eine andere Möglichkeit ist, dass du dir mal die BackgroundWorker-Klasse anschaust.
 
Okay...habe nochmal drüber nachgedacht und bin mittlerweise auf dem folgendem Stand:

Code:
using System.Threading;

namespace Thread2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            
            //ThreadStart del = new ThreadStart(SecoundThread);
            Thread sec = new Thread(new ParameterizedThreadStart(SecoundThread));
            sec.Start(this);
            progressBarTest.Minimum = 0;
            progressBarTest.Maximum = 20;
            progressBarTest.Value = 0;
            progressBarTest.Step = 1;
            
        }

        public static void SecoundThread(object fParam)
        {
            Form1 lForm = (Form1)fParam;
            
            for (int i = 0; i < 20; i++)
            {
                //lForm.labelTest.Text = "Arg :: " + i;
                lForm.SetState(i);
                Thread.Sleep(400);
            }
        }

//InvokeRequired vergleicht doch normal Thread der UI-Control mit dem des Callers, wenn 2 verschiedene Threads, dann true, wenn er 2 verschiedene Threads hat, soll er nochmal im Thread1 starten

        public void SetState(int fParam)
        {
            if (this.InvokeRequired)                 
            {
                this.SetState(fParam);
            }
            else
            {
                this.progressBarTest.Value = fParam;
            }
        }

Aaaaber es läuft noch nicht, wie ichs will. Wenn ich das Programm ausführe, dann macht er mir einen tollen Fehler mit Bezeichnung StackOverflowException.
Ich habe mal gegoogelt :google: und herausgefunden, dass das mit zu oft verschachtelten Methoden verursacht wird.
Theoretisch dürfte es aber so laufen, oder etwa nicht?! Oder kann ich das über Variablen lösen wie z.B.:

Code:
        private void buttonStart_Click(object sender, EventArgs e)
        {
            
            //ThreadStart del = new ThreadStart(SecoundThread);
            Thread sec = new Thread(new ParameterizedThreadStart(SecoundThread));
            sec.Start(this);
            progressBarTest.Minimum = 0;
            progressBarTest.Maximum = 20;
            progressBarTest.Value = 0;
            progressBarTest.Step = 1;
            
        }


public static void SecoundThread(object fParam)
{
     Form1 lForm = (Form1) fParam;
     lForm.progressBarTest.PerformStep();
}

oder über globale variable, und mittels einer timerfunktion, wobei ich nicht genau weiß, wie das dann aussehen sollte

Code:
globale Deklaration/Initialisierung unter anderen von 
String progressStateValue;

        private void buttonStart_Click(object sender, EventArgs e)
        {
            
            //ThreadStart del = new ThreadStart(SecoundThread);
            Thread sec = new Thread(new ParameterizedThreadStart(SecoundThread));
            sec.Start(this);
        }

         public static void SecoundThread(object fParam)
         {
                Form1 lForm = (Form1) fParam;
                lForm.progresstatevalue=5;
         }

  //Timer funktion, soll alle 100 ms die Oberfläche, bzw. die Komponenten aktualisieren, bzw. den Wert eintragen
ProgressBarTest.Value = progressstatevalue;


Ich hoffe, ihr könnt mir zu den Lösungsvorschlägen weiterhelfen und diese ergänzen.

Habt Dank, Hawkings
 
Hab nicht direkt verstanden was du brauchst, aber hast du dir schonmal BackgroundWorker angesehen, vielleicht ist es das was du suchst.
 
Hat sich...habe es hinbekommen...


Code:
//Thread2

{
                RegistryKey regkey1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Distribution");
                int values = Int32.Parse(regkey1.GetValue("ProgressBar").ToString());
                SetStateBar(values);
}

public delegate void SetStateBarDelegate(int values);

        public void SetStateBar(int values)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new SetStateBarDelegate(SetStateBar), new object[] { values });
            }
            else
            {
                this.progressBar1.Value = values;
                Thread.Sleep(200);
            }
        }

Merci :)
 

Neue Beiträge

Zurück