| 

.NET C# Java Javascript Exception

2
Ich durchschaue nicht, wie genau die Lebensdauer bei Objekten geregelt wird, die einen asynchronen Callback behandeln sollen.

Konkretes Beispiel:

// Aufrufender Code
public void openfile (string fn) {
var loader = new Loader (fn, data, fileloaded);
loader.openfile();
}
private void fileloaded (FooFile foofile_, string info_)
{
// ...
}
// Aufgerufener Code
class Loader
{
// ...
public delegate void FooFileConsumer (FooFile foofile, string info);
private FooFileConsumer consumer;
public Loader(string filename_, MyData data_, FooFileConsumer consumer_)
{
// ...
consumer = consumer_;
}
public void openfile()
{
var webclient = new WebClient();
webclient.OpenReadCompleted += onopenfile;
// ...
webclient.OpenReadAsync(uri);
}
private void onopenfile (Object sender, OpenReadCompletedEventArgs e)
{
// ...
consumer.Invoke (foofile, info);
}


// ...
}


Jemand bis hier gekommen?

Meine Fragen:
(1) Was bewirkt, dass die Objekte loader und webclient zum Zeitpunkt der Callbacks noch nicht von der Garbage Collection abgeräumt sind?
(2) Was bewirkt, dass diese Objekte nach dem Callback abgeräumt werden können?
(3) Muss ich irgendetwas händisch machen um (1) oder (2) sicherzustellen?

Dabei habe ich zu (1) eher schon eine Theorie: webclient wird schon so konstruiert sein, dass es den Callback erlebt und über den Delegaten, der in webclient.OpenReadCompleted gespeichert wird, überlebt deswegen auch loader. Aber (2) ist mir ein Rätsel.
News:
07.09.2009
pjacobi 1,1k 2 6
2 Antworten
1
1) Es existieren ja noch Referenzen zum WebClient Objekt (zb. Sender im Callback). Möglicherweise willst du ja noch auf den WebClient zugreifen...

2) ?
Wahrscheinlich ist dann der Gültigkeitsbereich (Scope) der Methode zu Ende...

3) Ich würde das WebClient Objekt als Klassenvariable machen und im Loader IDisposable implementieren und dort das Loader objekt aufräumen. von using-Klausel in OpenFile(...) rate ich ab.

Wenn du asynchron programmiren willst , würde ich mal einen Blick auf Action<T> und Func<T, TResult> werfen. damit kannst du elegante Sachen machen...
07.09.2009
bubu 21 1 1
Re 2) Keine der Callback-Routinen (fileloaded, onopenfile) hat ja eine Stackvariable, die eine Referenz auf webclient oder loader hält. In dem Sinne ist (mir) nicht klar, wieso irgendetwas nach Abarbeiten des Callbacks passieren sollte.
pjacobi 07.09.2009
1
OpenReadAsync nutzt intern einen Thread, der unabhängig von einer ihn referenzierenden Variable läuft. Da der Code bis zum Aufruf von OpenReadAsync synchron läuft und erst danach die Referenzen freigegeben werden ist der Thread im Hintergrund schön weiter am Werkeln.

Durch webclient.OpenReadCompleted += onopenfile; existiert Threadintern eine Referenz auf die Callback-Methode was bewirkt, dass die Instanz der Klasse Loader nicht freigegeben wird.

Also: Du hast keine Referenzen mehr auf die Objekte, aber durch den Thread arbeiten sie noch.
Besser: Um den Thread abbrechen/stoppen/... zu können solltest Du eine Referenz vorhalten...funktionieren tut es auch so ;)

Edit: Kann nicht selbst kommentieren, also die Antwort hier: Keine Freigabe nötig :)
08.09.2009
DaSpors 3,4k 1 8
DaSpors 3,4k 1 8
Gut. Und die Freigabe passiert auch wieder automatisch, d.h. insbesonder ist kein "webclient.OpenReadCompleted -= onopenfile;" nötig?
pjacobi 08.09.2009

Stelle deine .net-Frage jetzt!