Será que o coletor de lixo destrói temporariamente objetos sem referência durante chamadas assíncronas em .NET?

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

Pergunta

Imagine que eu vou fazer uma chamada assíncrona no .NET, ou seja HttpWebRequest.BeginGetResponse, eo objeto HttpWebRequest não é referenciado em um escopo mais amplo. Será que o coletor de lixo destruí-lo e causar problemas?

código Exemplo:

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..
    }
}

Versão alternativa (com o pedido que está sendo passado como um AsyncState):

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..
    }
}
Foi útil?

Solução

Um objeto é considerado vivo e não-elegíveis para coleta de lixo se algum fio vivo contém uma referência a ele, ou se ele é referenciado estaticamente (direta ou indiretamente, em ambos os casos).

Em ambos os exemplos da API assíncrona mantém uma referência ao seu pedido (dentro do pool de threads, onde assíncrono operações de IO são apresentados) e por isso não vai ser lixo coletado até completar.

Outras dicas

Não, o coletor de lixo não vai lhe causar problemas.

Não presuma que porque você não tem acesso ao objeto, o coletor de lixo está indo para limpá-lo.

O coletor de lixo começa com uma série de "raízes" - objetos e referências que são conhecidos acessível. Então, todos os objetos acessível a partir dessas raízes são encontradas, e tudo o mais é coletado.

Cada segmento em execução -. Incluindo o segmento (s) que processam as chamadas assíncronas são incluídos na lista de raízes

Se um objeto não tem referências, tanto quanto o GC está em causa, então você não pode mais get uma referência a ele. Então você não pode ter um objeto que temporariamente não tem uma referência a ele.

(Isso pressupõe nada sorrateira como jogos de código de jogo não gerenciados ou não seguros)

o objeto permanece referenciada muito bem, pela implementação de chamadas assíncronas - que precisa manter uma lista de todos os pedidos em aberto, para os dados de entrada correlacionam-se com os pedidos. Muito provavelmente, .NET utiliza uma variável global (ou classe) para armazenar os pedidos.

No primeiro exemplo de código, por que você criar Request, se você não usá-lo?

De qualquer maneira, se nenhuma referência (directa ou indirecta) existe para um objecto a partir de qualquer um dos objectos actualmente no âmbito da GC pode recolhê-lo.

Assim, no seu primeiro exemplo quando o programa sai método principal solicitação ainda está no escopo (em outro segmento) para que ele não vai ficar recolhido até a chamada terminar assíncrona. Em seu segundo exemplo, ambos, o segmento thread-piscina, e seu código manter um referrence ao seu objeto, por isso, obviamente, não vai ficar recolhido também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top