Hat der Garbage Collector zerstören vorübergehend nicht referenzierte Objekte während asynchroner Anrufe in .NET?

StackOverflow https://stackoverflow.com/questions/421547

Frage

Stellen Sie sich vor, dass ich einen Asynchron-Aufruf in .NET machen, das heißt HttpWebRequest.BeginGetResponse und das HttpWebRequest-Objekt nicht in einem breiteren Umfang verwiesen. Wird der Garbage Collector es zerstören und Probleme verursachen?

Beispielcode:

using System;
using System.Net;

public class AsyncHttpWebRequest
{
    void Main()
    {
        var Request = HttpWebRequest.Create("http://www.contoso.com");
        var result = Request.BeginGetResponse(GetResponseCallback, null);
    }

    private void GetResponseCallback(IAsyncResult AsyncResult)
    {
        // Do Something..
    }
}

Alternate Version (mit dem Antrag als AsyncState geführt wird):

using System;
using System.Net;

public class AsyncHttpWebRequest
{
    void Main()
    {
        var Request = HttpWebRequest.Create("http://www.contoso.com");
        var result = Request.BeginGetResponse(GetResponseCallback, Request);
    }

    private void GetResponseCallback(IAsyncResult AsyncResult)
    {
        // Do Something..
    }
}
War es hilfreich?

Lösung

Ein Objekt wird als lebendig und nicht förderfähige für die Garbage Collection, wenn ein Live-Thread einen Verweis darauf enthält, oder wenn es statisch verwiesen (direkt oder indirekt in beiden Fällen).

In beiden Beispielen die Asynchron-API einen Verweis auf Ihre Anfrage (im Thread-Pool, wo async IO-Operationen eingereicht werden) hält und so wird es nicht Müll gesammelt werden, bis er abgeschlossen ist.

Andere Tipps

Nein, wird der Garbage Collector nicht Probleme verursachen.

Sie nicht davon ausgehen, dass, weil Sie hat keinen Zugriff auf das Objekt, die Garbage Collector es aufzuräumen wird.

Der Garbage Collector beginnt mit einer Reihe von „Wurzeln“ - Objekte und Referenzen, die erreichbar sind bekannt. Dann werden alle Objekte erreichbar von den Wurzeln gefunden werden, und alles andere wird gesammelt.

Jeder laufenden Thread -. Einschließlich der Faden (en), die die Async Anrufe verarbeiten sind in der Liste der Wurzeln enthalten

Wenn ein Objekt keine Referenzen hat, so weit das GC betroffen ist, dann können Sie nicht mehr get ein Hinweis auf sie. So können Sie nicht ein Objekt, dass vorübergehend haben keinen Hinweis auf sie.

(Dies setzt voraus, nichts hinterhältig wie nicht verwaltete oder unsicheren Code für Spiele)

Das Objekt bleibt referenzierten ganz gut, durch die Implementierung von Asynchron-Anrufen - die Liste aller offenen Anfragen beibehalten muss, um eingehende Daten zu den Anfragen zu korrelieren. Wahrscheinlich nutzt .NET ein globales (oder Klasse) Variable, um die Anfragen zu speichern.

Im ersten Beispiel-Code, warum erstellen Sie anfordern, wenn Sie es nicht benutzen?

Wie auch immer, wenn keine Referenz (direkt oder indirekt) besteht zu einem Objekt von einem der Objekte zur Zeit in Rahmen der GC können sammeln es.

Also in Ihrem ersten Beispiel, wenn das Programm beendet Anfrage Main-Methode ist immer noch in ihrem Umfang (in einem anderen Thread), so wird es nicht gesammelt werden, bis das Asynchron Gespräch beendet. In Ihrem zweiten Beispiel sowohl der faden Pool Thread, und den Code halten eine referrence zu Ihrem Objekt, so wird es natürlich nicht so gut gesammelt bekommen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top