Re: Threads und BackgroundWorker
Es sollen nur Demos für mich sein, um zu verstehen, wie Threads unter .NET funktionieren.
Wenn ich es jetzt wie vorgeschlagen mache, bekomme ich folgende Fehlermeldung: Zitat:
Code:
private void button1_Click(object sender, EventArgs e)
{ if (rbThread.Checked) { Thread t = new Thread(ThreadProc); t.Start(); lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); } else { backgroundWorker1.RunWorkerAsync(); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < 1000; i++) { backgroundWorker1.ReportProgress((int)i / 10); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { lblStatusText.Text = resManager.GetString("BkWorkerStatusRunning"); } |
Re: Threads und BackgroundWorker
Ich selbst bin ein Fan vom BeginInvoke/EndInvoke Pattern.
Ich kann dadurch X Operationen asynchron starten, andere Dinge erledigen, und dann wenn ich das Ergebnis brauche, wartet der Code halt auf den Rückgabewert oder er hat ihn schon. Das ganze lässt sich auch so verpacken, dass man sich eine Factory für Delegates baut, die dann entweder warten oder den bestehenden Wert zurück geben. Um nicht soviel drumrum posten zu müssen, habe ich es mal nur mit lokalen Delegates gelöst: (Kein Delphi Code!)
Delphi-Quellcode:
Mit Futures wird das dann schon zu einem totalen no-brainer. :-)
var r : Random := new Random();
var myCall := method(parameter1, parameter2 : String) : Integer; begin Thread.Sleep(5000); exit r.Next(0, 1000); end; var getAsyncCall := method(parameter1, parameter2 : String) : Func<Integer>; begin var resultRef := new class(Value := default(nullable Integer)); var getValue : AsyncCallback := method(ar : IAsyncResult); begin locking resultRef do if not assigned(resultRef.Value) then resultRef.Value := myCall.EndInvoke(ar); end; var call := myCall.BeginInvoke(parameter1, parameter2, getValue, nil); result := method : Integer; begin getValue(call); exit valueOrDefault(resultRef.Value); end; end; var async1 := getAsyncCall('abc', 'def'); var async2 := getAsyncCall('ghi', 'jkl'); // do soemthing... Thread.Sleep(2500); var result1 := async1(); var result2 := async2(); var result3 := async1();
Delphi-Quellcode:
var future1 := async myCall('abc', 'def');
var future2 := async myCall('ghi', 'jkl'); |
Re: Threads und BackgroundWorker
Langsam, langsam langsam. Anstatt mit immer neuen Lösungen zu kommen, wäre es mir lieb, wenn wir erstmal meine Probleme mit den vorhandenen Lösungen besprechen könnten.
|
Re: Threads und BackgroundWorker
Hallo Michael,
Zitat:
Code:
Das kann natürlich mit String.Format() o.a. sehr verschönert werden. Das Prinzip ist aber, dass Du über ProgressChangedEventArgs.ProgressPercentage den aktuellen Stand (wie er über ReportProgress gesetzt wird) und über ProgressChangedEventArgs.UserState sogar einen bestimmten Wert (z.B. den aktuellen Datensatz, der natürlich ebenfalls gesetzt werden müsste) erhältst.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{ lblStatusText.Text = e.ProgressPercentage.ToString() + resManager.GetString("BkWorkerStatusRunning"); } Gruß Jürgen |
Re: Threads und BackgroundWorker
Es passiert zur Laufzeit und zwar in dieser Zeile:
Code:
Deine Lösung dürfte also das Problem nicht beheben.
backgroundWorker1.ReportProgress((int)i / 10);
|
Re: Threads und BackgroundWorker
Zitat:
|
Re: Threads und BackgroundWorker
Hi Luki,
in der MSDN gibt es ein leicht verständliches Beispiel zum BackgroundWorker, nennt sich: "Ausführen eines Vorgangs im Hintergrund" und ist unter Beispiele BackgroundWorker-Klasse zu finden. |
Re: Threads und BackgroundWorker
Zitat:
|
Re: Threads und BackgroundWorker
So wir haben es gleich geschafft. Nur noch zwei, drei Dinge.
Ich rufe die Methode CancelAsync() auf, um den BackgroundWorker zu stoppen. Allerdings schein dann das Fenster nicht mehr zu reagieren und gestoppt wird anscheinen auch nichts:
Code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{ if (backgroundWorker1.CancellationPending) { lblStatusText.Text = resManager.GetString("BkWorkerUserCancel"); e.Cancel = true; } for (int i = 0; i < 10000000; i++) { backgroundWorker1.ReportProgress((int)i / 10); Thread.Sleep(0); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { lblStatusText.Text = resManager.GetString("BkWorkerStatusRunning"); this.Update(); } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { lblStatusText.Text = resManager.GetString("BkWorkerStatusFinish"); } |
Re: Threads und BackgroundWorker
Wo in deinem Code prüfst du denn, dass er abrechen soll?
Außer direkt am Anfang vor der Schleife natürlich... ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz