Threads und Steuerelemente, gehts auch einfacher?

17/10/2007 - 00:58 von Tseng S. | Report spam
Hallo,
ich erstelle oft ein neuen Thread, in dem Daten verarbeitet werden, bei dem
ich möchte, dass auch der Hauptthread über den Fortschritt informiert wird
(z.B. ProgressBar updaten).

Im Moment löse ich das mit hilfe von Delegates und Events, etwa wie folgt:

public partial class frmMain : Form {
public struct ProgressInfo {
public int start;
public int end;
public int value;
};

ProgressInfo progressInfo = new ProgressInfo();

public delegate void ProgressInfoHandler(ref ProgressInfo progInfo);

public event ProgressInfoHandler Progress = null;
public void OnProgress(ref ProgressInfo progInfo) {
if(Progress != null) {
Progress(ref progInfo);
}
}
public frmMain() {
InitializeComponent();
this.Progress += new ProgressInfoHandler(this.ProgressUpdated);
}
private void btnStartThread_Click(object sender, EventArgs e) {
thread = new Thread(new ThreadStart(this.MyThread));
thread.Start();
}
void Dat2DDS() {
// Thread verarbeiten
progressInfo.start = 0;
progressInfo.end = 100;
for(int i=0;i<100;i++){
progressInfo.value = i;
OnProgress(ref progressInfo);
}
}

private void ProgressUpdated(ref ProgressInfo progInfo) {
this.Invoke(new ProgressInfoHandler(UpdateProgressBar), new
object[] { progInfo} );
}
private void UpdateProgressBar(ref ProgressInfo progInfo){
progressBar.Minimum = progInfo.start;
progressBar.Maximum = progInfo.end;
progressBar.Value = progInfo.value;
}
}

Es funktioniert an sich wunderbar. Allerdings stört mich dabei eine
Kleinigkeit und zwar, dass ich quasi für jeden solchen Thread eine Funktion
schreiben muss, die "this.Invoke(...)" aufruft. Mir gefàllt diese weise
nicht besonders und macht meiner Meinung nach den Code etwas unleserlicher.
Gibt es ein Weg, es direkt zu machen, ohne dass meine eine
Zugriffsverletzung kriegt?

Ich hab versucht, statt
public void OnProgress(ref ProgressInfo progInfo) {
if(Progress != null) {
Progress(ref progInfo);
}
}
folgendes hinzuschreiben:
public void OnProgress(ref ProgressInfo progInfo) {
if(Progress != null) {
Progress.Invoke(ref progInfo);
}
}
aber, dass hat nicht den gewünschten Effekt gebracht. Ich krieg die selber
Threadübergreifende Zugrifsverletzungsmeldung, wie wennn ich direkt aus dem
Thread versuche auf das ProgressBar Steuerelement zuzugreifen.

Bye
Tseng S.
 

Lesen sie die antworten

#1 Frank Dzaebel
17/10/2007 - 07:42 | Warnen spam
Hallo Tseng,

Es funktioniert an sich wunderbar. Allerdings stört mich dabei eine
Kleinigkeit und zwar, dass ich quasi für jeden solchen Thread eine
Funktion schreiben muss, die "this.Invoke(...)" aufruft. Mir gefàllt diese
weise nicht besonders und macht meiner Meinung nach den Code etwas
unleserlicher. Gibt es ein Weg, es direkt zu machen, ohne dass meine eine
Zugriffsverletzung kriegt?



Es gibt zum Beispiel den BackgroundWorker:

[Bearbeiten von Steuerelementen aus Threads]
http://dzaebel.net/ControlInvoke.htm

Oder auch "Anonyme Methoden":

[C#: Erstellen eleganten Codes mit anonymen Methoden, Iteratoren und
partiellen Klassen]
http://msdn.microsoft.com/msdnmag/i...spx?loc=de


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen