2 Stimmen

C# Get-Thread-Klassen zur Kommunikation mit der Hauptklasse

Ich habe einige C#-Threads, die einige Arbeit auf der Grundlage von Zahlen zu tun haben, aber ich bin unsicher, wie die Thread-Objekte zu erhalten, zurück zu der Hauptprogrammklasse zu kommunizieren. Ich brauche es, um das Hauptobjekt zu sagen, dass es das Ergebnis gefunden hat und was das Ergebnis ist, dann kann es die Threads stoppen.

        Worker Worker1 = new Worker(input, 1073741824, 2147483647);
        Worker Worker2 = new Worker(input, 0, 1073741824);
        Thread ThreadRace1 = new Thread(new ThreadStart(Worker1.Start));
        Thread ThreadRace2 = new Thread(new ThreadStart(Worker2.Start));
        ThreadRace1.Start();
        ThreadRace2.Start();

2voto

Justin Pihony Punkte 63852

Wenn Sie .NET 4.0+ verwenden, dann können Sie die TPL . Der Code würde etwa so aussehen:

var task1 = Task.Factory.StartNew<int>(()=>
    {
        //Do Work...use closures, or you can pass boxed arguments in
        //via StartNew params
        return 1;//return the value that was computed
    });
var task2 = Task.Factory.StartNew<int>(()=>
    {
        //Do Work
        return 2;//return the value that was computed
    });
task1.ContinueWith((previousTask)=>
    {
        //Return back to the main thread
        label1.Text += "The value of task1 is going to be 1-->" 
                       + previousTask.Result;
    }
    , new CancellationTokenSource().Token, TaskContinuationOptions.None,
    //This is to auto invoke back into the original thread
    TaskScheduler.FromCurrentSynchronizationContext()); 
task2.ContinueWith((previousTask)=>
    {
        //Return back to the main thread
        label1.Text += "The value of task2 is going to be 2-->" 
                       + previousTask.Result;
    }
    , new CancellationTokenSource().Token, TaskContinuationOptions.None,
    //This is to auto invoke back into the original thread
    TaskScheduler.FromCurrentSynchronizationContext()); 

Wenn Sie sich nicht um jeden einzelnen kümmern müssen, können Sie warten, bis sie alle zurückkommen:

var taskList = new List<Task>{task1,task2};
Task.Factory.ContinueWhenAll(taskList.ToArray(), 
    (tasks)=>
    {
        label1.Text = "Results are: ";
        foreach(var task in tasks)
        {
            //process each task
            label1.Text += task.Result + "|";
        } 
    }, 
    new CancellationTokenSource().Token, TaskContinuationOptions.None,
    //This is to auto invoke back into the original thread
    TaskScheduler.FromCurrentSynchronizationContext());

1voto

Bojin Li Punkte 5709

Es gibt bereits eine Rahmenklasse namens BackgroundWorker das Ihnen dabei helfen soll, die Menge an Code, die Sie für die Hintergrundverarbeitung schreiben müssen, zu minimieren. Sie können Ihren Hauptthread für verschiedene Callback-Ereignisse des BackgroundWorkers registrieren lassen, insbesondere für das Ereignis "OnRunWorkerCompleted", wenn der BackgroundWorker-Thread die Ausführung seiner Aufgabe beendet.

Hier ein kurzes Beispiel, wie Sie es einrichten. Sie werden die BackgroundWorker-Instanzen in Ihrem Haupt-Thread starten.

    void SetupBackgroundworkers()
    {
        BackgroundWorker backgroundWorker1 = new BackgroundWorker();
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
        backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

        BackgroundWorker backgroundWorker2 = new BackgroundWorker();
        backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
        backgroundWorker2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker2_RunWorkerCompleted);

        // Start the workers
        backgroundWorker1.RunWorkerAsync();
        backgroundWorker2.RunWorkerAsync();
    }

    void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var result = e.Result; // read result
    }

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var result = e.Result; // read result
    }

    void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
        // perform work...
        e.Result = 1;  // your result
    }

    void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // perform work...
        e.Result = 2;  // your result
    }

0voto

Cristian Lupascu Punkte 36824

Einige Möglichkeiten:

  1. eine Referenz der Hauptklasse an jeden Worker über den Worker-Konstruktor übergeben. Auf diese Weise können Sie eine public Methode, die von der Hauptklasse
  2. einberufen public static Methode, die von der Hauptklasse ausgesetzt wird (die schmutzigste Lösung; unbedingt vermeiden)
  3. wenn Sie C# 4.0 verwenden, können Sie die Task Parallel Library's WaitAny Methode, um die Kontrolle in der Hauptklasse zu erhalten, wenn tous der Arbeiter sind fertig

Die ersten beiden Optionen erfordern explizite Maßnahmen zur Gleichzeitigkeitskontrolle (stellen Sie sicher, dass, nachdem ein Arbeiter die Hauptklasse signalisiert hat, kein anderer Arbeiter dies tun kann).

0voto

Paul Sullivan Punkte 2857

Sie können entweder:

eine globale Variable innerhalb des Threads setzen (allerdings gibt es dann Synchronisationsprobleme, wenn mehrere Threads dieselben Variablen verwenden)

OR

Verwenden Sie ParameterisedThreadStart, das die Übergabe eines Objekts erlaubt (das Sie als out (by reference) Variable verwenden können).

ODER Sie können eine Threadmanager-Klasse erstellen, die eine Methode hat, die bei Abschluss von jedem Thread, den sie startet, aufgerufen wird - die Methode könnte eine Signatur haben (aber das liegt an Ihnen, und mein Code ist semi-psuedocode)

static class ThreadManager{

    ctor Main(blah blah){//do thread creation and in loop you can call Threadmanager.ThreadFinished as it is static method}

    public static object ThreadFinished(Thread theThreadThatJustFInished, object data)
    {
        //do update on ThreadManager based on object data and Thread type
    }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X