2012-08-05 5 views
5

Ich verwende die Memory Management während die Daten wie folgt zurückgeben.Verwenden von Anweisung während der Rückgabe von Daten

private DataSet ReturnDs() 
{ 
    using (DataSet ds = new DataSet()) 
    { 
     return ds; 
    } 
} 

Abfrage - Gibt es eine Frage, die ‚Verwendung‘ Statement bei der Platzierung, während die Daten der Rückkehr? Ich bekomme immer noch das komplette Schema sowie die Daten in der Empfangsfunktion?

+2

Wenn Sie ein Objekt zurückgeben möchten, warum möchten Sie es entsorgen? –

+0

@Mert - Ich möchte wissen, was der Schaden ist? Gibt es Datenverluste? Ich habe bestätigt, dass es in Ordnung ist ... Meine Frage ist - gibt es etwas nicht vorteilhaftes, dass ich vermisse? –

+0

Sie haben es verifiziert? Nett. Viel zu wenige Leute beweisen tatsächlich ihren Code mit formalen Methoden :) – Joey

Antwort

4

Dies ist definitiv ein falsches Muster. Der einzige Grund, dass es jetzt für Sie funktioniert, ist, dass DataSet.Dispose() eigentlich ein Dummy ist.

using (DataSet ds = new DataSet()) 
{ 
    return ds; 
} // there is a ds.Dispose() here but it does nothing. 

Wenn Sie den Datensatz mit Instanz, die Sie keine Daten in der aufrufenden Funktion sehen wäre ein Enitity Rahmen DbContext dann ersetzen.

+0

danke für deine unterstützung .. kannst du bitte sagen warum? –

+0

+1 Jedes Objekt, das in seiner Dispose-Methode tatsächlich etwas Sinnvolles tut, würde in der aufrufenden Methode als "ungültig" erscheinen. –

+0

@HenkHolterman - können Sie bitte einen Link teilen, um zu erklären, ** es gibt eine ds.Dispose() hier, aber es tut nichts **. –

0

Ich bin mir nicht sicher, was genau Ihre Frage ist.

Sobald die Methode endet, indem Sie etwas neu abstimmen, wird ds.Dispose() automatisch aufgerufen.

Dies bedeutet, dass das DataSet, das Ihre Methode zurückgibt, bereits entsorgt wird, wenn Ihre aufrufende Methode es empfängt.

0

als Mert-Kommentar, beachten Sie, dass Sie das Objekt, das Sie zurückgeben, entsorgen. aber im Grunde ist die Verwendung tatsächlich ein Versuch/schließlich und die Beseitigung wird die Methode zurückgerufen werden. Die Auswirkung hängt von der IDisposable-Implementierung für jeden Typ ab. Normalerweise sollten Sie die Entität, die Sie zurückrufen, nicht zurückweisen (kill), die sie wahrscheinlich verwenden wird.

+0

»raus aus dem Umfang« .. Ich glaube nicht, dass diese Aussage hier einen Sinn ergibt. – Joey

2

Verwenden Sie die using-Anweisung in der aufrufenden Methode, nicht die Methode, die das Objekt zurückgibt.

public void Caller() 
{ 
    using(DataSet ds = GetDataSet()) 
    { 
    // code here 
    } 
} 

public DataSet GetDataSet() 
{ 
    // don't use a using statement here 
    return ds; 
} 

Die using Anweisung ist grundsätzlich die gleiche wie, dies zu tun:

DataSet ds = null; 
try 
{ 
    // code here 
} 
finally 
{ 
    if(ds != null) 
    { 
    ds.Dispose(); 
    ds = null; 
    } 
} 

Also, wenn Sie eine using Anweisung in einem Verfahren verwendet, das angeblich das Objekt in der using Anweisung zurückzukehren, wäre es Rückgabe eines disponierten Objekts (dh geschlossener Stream, geschlossener Datensatz usw.), was bedeutet, dass einige der internen Objekte null oder geschlossen sein können. Mit anderen Worten, alle internen Ressourcen würden aufgeräumt werden, was den Zweck der Implementierung von IDisposable überhaupt darstellt. Wenn Ihre Anwendung darauf angewiesen ist, dass einige dieser internen Ressourcen verfügbar sind, z. B. bei Verwendung eines Stream-Objekts, wird eine Ausnahme ausgelöst. Bitte beachten Sie, dass nicht alle finally Blöcke gleich geschrieben sind. Denken Sie daran, IDispoable wurde implementiert, um alle internen Ressourcen und nicht verwalteten Objekte zu bereinigen. Diese internen Ressourcen werden möglicherweise nicht außerhalb der using-Anweisung benötigt, sodass die Verwendung der using-Anweisung manchmal so aussieht, als ob sie ordnungsgemäß funktioniert, aber es wird nicht empfohlen und wird definitiv nicht mit allen Objekten funktionieren. Wenn sich Microsoft dazu entschloss, das DataSet-Objekt in einer zukünftigen Version zu ändern und damit etwas Wichtiges für Ihre Anwendung zu entfernen, würde Ihr Arbeitscode plötzlich nicht mehr funktionieren.

+0

Kannst du plz erklären warum? –

+0

@RGI - aktualisierte Antwort. –

+0

Ein Downvote ?? Wie ist diese Antwort nicht hilfreich? –

4

Im Allgemeinen ist die Entsorgung eines Objekts, das Sie zurückgeben wollen, ein Fehler: Ihr Code ist mit diesem Objekt nicht fertig und Sie werden dem Anrufer ein defektes Objekt übergeben.

Also in der Tat: nicht Dispose() das, was bedeutet: nicht using auf ein Objekt verwenden, die Sie zurückgeben werden.Es liegt an dem Anrufer, es zu entsorgen: Sie sind jetzt der Besitzer. Dies sollte idealerweise in der API dokumentiert werden.

Allgemeiner müssen Sie jedoch auch über Ausnahmen nachdenken. Was passiert, wenn Ihre Methode Fehler? Für komplexe Szenarien benötigen Sie möglicherweise Folgendes:

, um sicherzustellen, dass das Objekt im Fehlerfall ordnungsgemäß entsorgt wird.

+0

+1 Weil du dasselbe wie Henk sagst. Genau genommen handelt es sich auch nicht um einen Fehler, es ist einfach nutzlos und sinnlos, zurückzugeben, was für einen Anrufer ein totes Objekt sein kann (und allgemein sein wird). –

+0

Ich bekomme keinen Fehler ... –

+0

@RGI das ist, weil für DataSet Dispose ein No-Op ist: http://StackOverflow.com/Questions/913228/Should-I-Dispose-Dataset-and-Datatable Und Deshalb habe ich * im allgemeinen Fall * geantwortet. Was Sie jedoch tun, ist verwirrend und könnte zu Fehlern für jeden anderen Typ führen. Tu es nicht. –

Verwandte Themen