Benutzer mit den meisten Antworten
BackgroundWorker / übergabe von Objekt

Frage
-
Hallo,
ReportProgress kann ich über einen Background Worker ausgeben, das funktioniert. Gibt es auch eine Möglichkeit z.B. einen String an die GUI zu übermitteln?
vielen Dank
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 22. September 2011 07:32 Titel Korrektur: war Backgroundworker / übergabe von Ojekt
Antworten
-
Hallo,
Es gibt eine Überladung der Methode ReportProgress, die zwei Parameter besitzt: Int32 und Object. Den letzten Parameter hat man bewußt als Object belassen, damit man einen beliebigen Zustand (userState) an den UI-Thread übergeben kann. Du kannst im userState einen String aber auch eine Instanz einer beliebigen anderen Klasse übergeben. Beim Verarbeiten auf dem UI-Thread im ProgressChanged-Ereignishandler mußt Du nur korrekt casten:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { backgroundWorker.ReportProgress(100, "Complete!"); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { toolStripStatusLabel.Text = e.UserState as String; }
Im obigen Beispiel, das aus der MSDN-Dokumentation stammt, wird der String "Complete!" an die UI übermittelt. Schau dir das Beispiel in Ruhe an. Dort findest Du auch, wie man auf ein UI-Steuerelement über einen Delegate bzw. Control.Invoke() aus einem Fremdthread sicher zugreift.
BackgroundWorker.ReportProgress-Methode (Int32, Object):
http://msdn.microsoft.com/de-de/library/a3zbdb1t.aspxDen vollständigen Code findest Du hier:
http://msdn.microsoft.com/de-de/library/system.windows.forms.toolstripprogressbar.aspx
Gruß
Marcel- Als Antwort vorgeschlagen Heslacher Donnerstag, 22. September 2011 06:06
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 27. September 2011 12:41
Alle Antworten
-
Hallo,
Es gibt eine Überladung der Methode ReportProgress, die zwei Parameter besitzt: Int32 und Object. Den letzten Parameter hat man bewußt als Object belassen, damit man einen beliebigen Zustand (userState) an den UI-Thread übergeben kann. Du kannst im userState einen String aber auch eine Instanz einer beliebigen anderen Klasse übergeben. Beim Verarbeiten auf dem UI-Thread im ProgressChanged-Ereignishandler mußt Du nur korrekt casten:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { backgroundWorker.ReportProgress(100, "Complete!"); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { toolStripStatusLabel.Text = e.UserState as String; }
Im obigen Beispiel, das aus der MSDN-Dokumentation stammt, wird der String "Complete!" an die UI übermittelt. Schau dir das Beispiel in Ruhe an. Dort findest Du auch, wie man auf ein UI-Steuerelement über einen Delegate bzw. Control.Invoke() aus einem Fremdthread sicher zugreift.
BackgroundWorker.ReportProgress-Methode (Int32, Object):
http://msdn.microsoft.com/de-de/library/a3zbdb1t.aspxDen vollständigen Code findest Du hier:
http://msdn.microsoft.com/de-de/library/system.windows.forms.toolstripprogressbar.aspx
Gruß
Marcel- Als Antwort vorgeschlagen Heslacher Donnerstag, 22. September 2011 06:06
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 27. September 2011 12:41
-
Hallo,
ich wage es ( ;-) ) meine erste Antwort zu schreiben.
Als ich bei einem Projekt (sehr) viele Probleme mit dem BackgroundWorker hatte, habe ich mir sehr genau die Antworten von u. a. Marcel und Frank angeschaut. Meine Lösung sieht so aus:
void backgroundWorker_DoWork_Task( object sender, DoWorkEventArgs e ) { const int max = 127; BackgroundWorker bw = (BackgroundWorker) sender; bw.ReportProgress( 0, new ProgressInfo() { Maximum = max, Value = 0, Info = "Preparing task 2...", Style = ProgressBarStyle.Blocks } ); Thread.Sleep( 2500 ); for( int i = 0; i < max; i++ ) { if( bw.CancellationPending ) { e.Cancel = true; break; } bw.ReportProgress( 0, new ProgressInfo() { Maximum = max, Value = i, Info = "Task 2 is running...", Style = ProgressBarStyle.Marquee } ); Thread.Sleep( 55 ); } }
public class ProgressInfo { public static string InfoNofMText = "von"; #region Property: Minimum private int _Minimum; public int Minimum { get { return _Minimum; } set { _Minimum = value; } } #endregion #region Property: Maximum private int _Maximum; public int Maximum { get { return _Maximum; } set { _Maximum = value; } } #endregion #region Property: Value private int _Value; public int Value { get { if( _Value < _Minimum ) return _Minimum; if( _Value > _Maximum ) return _Maximum; return _Value; } set { _Value = value; } } #endregion #region Property: Style private ProgressBarStyle _Style = ProgressBarStyle.Continuous; public ProgressBarStyle Style { get { return _Style; } set { _Style = value; } } #endregion #region Property: Info private string _Info; public string Info { get { return _Info; } set { _Info = value; } } #endregion #region Property: ProgressPercentage public float ProgressPercentage { get { float result = 1; if( _Maximum > 0 ) result = ( _Value * 100 ) / ((float)_Maximum); return result; } } #endregion #region Property: ProgressPercentageInt public int ProgressPercentageInt { get { return Convert.ToInt32( this.ProgressPercentage ); } } #endregion #region Property: ProgressPercentageInfo public string ProgressPercentageInfo { get { return this.ProgressPercentage.ToString( "F2" ) + " %"; } } #endregion #region Property: InfoNofM public string InfoNofM { get { return String.Format( "{0} {1} {2}", _Value, ProgressInfo.InfoNofMText, _Maximum - _Minimum ); } } #endregion }
ich hoffe, es hilft Dir weiter.
P.
hmm, es fehlt noch was (das Casting, wovon Marcel gesprochen hat..).
_BackgroundWorker.ProgressChanged += new ProgressChangedEventHandler( backgroundWorker_ProgressChanged ); void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { ProgressInfo pi = (ProgressInfo)e.UserState; SetProgressInfoGUI(pi); } void SetProgressInfoGUI( ProgressInfo progressInfo ) { infoProgressBar.Minimum = progressInfo.Minimum; infoProgressBar.Maximum = progressInfo.Maximum; infoProgressBar.Style = progressInfo.Style; infoProgressBar.Value = progressInfo.Value; progressInfoLabel.Text = progressInfo.Info; progressNofMLabel.Text = progressInfo.InfoNofM; progressPercentageLabel.Text = progressInfo.ProgressPercentageInfo; }
...jetzt dürfte es komplett sein...
P.
- Bearbeitet Purclot Dienstag, 27. September 2011 15:07