가비지 수집기는 .NET에서 비동기 호출 중에 참조되지 않은 개체를 일시적으로 삭제합니까?

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

문제

.NET에서 비동기 호출을 한다고 상상해 보세요.HttpWebRequest.BeginGetResponse 및 HttpWebRequest 개체는 더 넓은 범위에서 참조되지 않습니다.가비지 컬렉터가 이를 파괴하고 문제를 일으킬까요?

예제 코드:

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

대체 버전(요청이 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..
    }
}
도움이 되었습니까?

해결책

라이브 스레드에 참조가 포함되어 있거나 정적으로 (직접 또는 간접적으로) 참조되는 경우 객체는 생생하고 쓰레기 수집에 적합하지 않은 것으로 간주됩니다.

두 예제에서 Async API는 요청에 대한 참조를 유지합니다 (Async IO 작업이 제출 된 스레드 풀 내에서). 따라서 완료 될 때까지 쓰레기를 수집하지 않습니다.

다른 팁

아니요, 쓰레기 수집가는 문제를 일으키지 않습니다.

그렇게 가정하지 마십시오 물체에 접근 할 수없고 쓰레기 수집가가 그것을 청소할 것입니다.

쓰레기 수집가는 도달 할 수있는 다수의 "뿌리" - 물체와 참조로 시작합니다. 그런 다음 해당 뿌리에서 도달 할 수있는 모든 물체가 발견되고 다른 모든 것이 수집됩니다.

비동기 호출을 처리하는 스레드를 포함한 각 실행 스레드는 루트 목록에 포함됩니다.

객체에 GC에 관한 한 참조가 없으면 더 이상 할 수 없습니다. 가져 오기 그것에 대한 참조. 그래서 당신은 그 물건을 가질 수 없습니다 일시적으로 그것에 대한 언급이 없습니다.

(이것은 관리되지 않거나 안전하지 않은 코드를 플레이하는 것처럼 비열한 것은 없습니다)

객체는 Async 호출을 구현하여 모든 열린 요청 목록을 유지 해야하는 Async 호출을 구현하여 수신 데이터를 요청과 관련시켜야합니다. .NET은 전체 (또는 클래스) 변수를 사용하여 요청을 저장합니다.

첫 번째 예제 코드에서는 Request를 사용하지 않는데 왜 생성합니까?

어쨌든, 현재 범위에 있는 개체 중 개체에 대한 참조(직접 또는 간접)가 없으면 GC 5월 그것을 수집하십시오.

따라서 첫 번째 예에서 프로그램이 종료될 때 Main 메서드 Request는 여전히 범위(다른 스레드에 있음)에 있으므로 비동기 호출이 끝날 때까지 수집되지 않습니다.두 번째 예에서는 스레드 풀 스레드와 코드 모두 개체에 대한 참조를 유지하므로 분명히 수집되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top