Laden...

BackgroundWorker im ViewModel: Liste ist, je nach timing, noch nicht instanziiert

Erstellt von Jessimaus vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.057 Views
J
Jessimaus Themenstarter:in
6 Beiträge seit 2017
vor 6 Jahren
BackgroundWorker im ViewModel: Liste ist, je nach timing, noch nicht instanziiert

Hallo Leute,

ich habe ein Problem bei der Verwendung des BackgroundWorkers.
Die Ausgangssituation ist folgende: Ich erstelle eine Instanz des ViewModels und übergebe dieses dann an das aufzurufende Formular.
Da für das Formular eine Liste mit mehreren 100tausend Datensätzen benötigt wird, die Datenleitung mitunter aber recht schlecht ist,
habe ich diese Liste mittels BackgroundWorker im OnLoad-Ereignis des Formulars nachgeladen. Nachdem ich diese Funktionalität ins
ViewModel verschoben habe, erhalte ich regelmäßig wenig aufschlussreiche Fehlermeldungen.> Fehlermeldung:

"Für den aktuellen Befehl ist ein schwerwiegender Fehler aufgetreten. Löschen Sie eventuelle Ergebnisse."

Im Konstruktor des ViewModels steht u.a. folgendes:

// ...
Worker = new BackgroundWorker{
	WorkerReportsProgress = true,
	WorkerSupportsCancellation = true
};
Worker.DoWork += worker_DoWork;
Worker.RunWorkerCompleted += worker_RunWorkerCompleted;

refresh_Geraeteliste();
} // End Konstruktor

DoWork:


private void worker_DoWork(object sender, DoWorkEventArgs e){
	IsEdit  = false;
	IsReady = false;
	var TmpCon = new MdbConnection{
		SqlCon	= MdbCon.SqlCon,
		//...
	};
	TmpListe = new LstListe(TmpCon);
}	// End worker_DoWork

RunWorkerCompleted:

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
	if(e.Cancelled) return;

	if(TmpListe.Count <= 0) return;
	ColGeraeteListe.Clear();			
	foreach(var _Item in TmpListe){
		ColGeraeteliste.Add(_Item);
	}
	ClvGeraeteliste.Refresh(); // CollectionViewSource
	IsReady = true;
}
private void refresh_GeraeteListe(){
	Worker.RunWorkerAsync();
	// ..			
}

private RelayCommand 	_CmdRefreshGeraeteliste;
public  ICommand	CmdRefreshGeraeteliste{
	get{
		return _CmdRefreshGeraeteliste ?? (_CmdRefreshGeraeteliste = new RelayCommand(
			param =>{
				TbxIsFocused = false;
				refresh_GeraeteListe();
				TbxIsFocused = true;
			},
			param => true));
	}
}

Das Problem ergibt sich dergestalt, dass die mittels Backgroundworker gefüllte temporäre Liste TmpListe innerhalb worker_RunWorkerCompleted oft NULL ist,
jedenfalls bei Aufruf von refresh_GeraeteListe() durch den Konstruktor. Wenn ich refresh_GeraeteListe() über das Command CmdRefreshGeraeteliste aufrufe, tritt das Problem scheinbar nicht auf.
Deklariert ist die TmpListe ja im ViewModel, gefüllt wird sie aber in einem anderen Thread als die Instanziierung des ViewModels. An der Stelle scheint mir der Hase im Pfeffer zu liegen. 😃
Ich würde mich freuen, könnte mir einer von euch ein wenig auf die Sprünge helfen.

Danke und Gruß
Jessimaus

1.040 Beiträge seit 2007
vor 6 Jahren

"Für den aktuellen Befehl ist ein schwerwiegender Fehler aufgetreten. Löschen Sie eventuelle Ergebnisse."

Tipp:
Um eine Fehlermeldung zu erhalten, mit der man auch Google füttern kann, das deutsche Sprachpaket deinstallieren bzw. die Sprache auf Englisch umstellen - damit kann man mehr anfangen. 😉

709 Beiträge seit 2008
vor 6 Jahren

Um eine Fehlermeldung zu erhalten, mit der man auch Google füttern kann, das deutsche Sprachpaket deinstallieren bzw. die Sprache auf Englisch umstellen - damit kann man mehr anfangen. 😉){gray}

Da hilft zur Not auch http://unlocalize.com

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

vermutlich gibt es im worker_DoWork eine Exception, bevor die TmpListe erstellt und zugewiesen ist.
Dann raucht Dir der BackgroundWorker ab, und Du bekommst es nicht mit, weil Du in worker_RunWorkerCompleted die e.Error-Property nicht auswertest. Da sollte die Exception drinstehen.

jedenfalls bei Aufruf von refresh_GeraeteListe() durch den Konstruktor. Wenn ich refresh_GeraeteListe() über das Command CmdRefreshGeraeteliste aufrufe, tritt das Problem scheinbar nicht auf.

Wenn das Ding einmal durchgelaufen ist, ist TmpListe ja schon initialisiert. Wenn der BackgroundWorker dann eine Exception verursacht, wird auch keine neue Liste zugewiesen. Im diesen Fall arbeitest Du dann aber mit den alten Daten aus dem letzten gelungenen Durchlauf.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca