Does the Garbage Collector destroy temporarily unr

2019-01-19 13:30发布

Imagine that I will make an async call in .NET, i.e. HttpWebRequest.BeginGetResponse, and the HttpWebRequest object isn't referenced at a broader scope. Will the Garbage Collector destroy it and cause problems?

Example code:

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 (with the request being passed as an 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..
    }
}

5条回答
做个烂人
2楼-- · 2019-01-19 14:09

If an object has no references as far as the GC is concerned then you can no longer get a reference to it. So you can't have an object that temporarily doesn't have a reference to it.

(This assumes nothing sneaky like unmanaged or unsafe code playing games)

查看更多
Melony?
3楼-- · 2019-01-19 14:11

No, the garbage collector won't cause you problems.

Don't assume that because you don't have access to the object, the garbage collector is going to clean it up.

The garbage collector starts with a number of "roots" - objects and references that are known reachable. Then, all the objects reachable from those roots are found, and everything else is collected.

Each running thread - including the thread(s) that process the Async calls are included in the list of roots.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-19 14:15

In the first example code, why do you create Request, if you don't use it?

Anyway, if no reference (direct or indirect) exists to an object from any of objects currently in scope the GC may collect it.

So in your first example when the program exits Main method Request is still in scope (in another thread) so it will not get collected until the async call ends. In your second example, both, the thread-pool thread, and your code keep a referrence to your object, so it obviously won't get collected as well.

查看更多
劳资没心,怎么记你
5楼-- · 2019-01-19 14:20

An object is considered alive and non-eligible for garbage collection if any live thread contains a reference to it, or if it's referenced statically (directly or indirectly in both cases).

In both examples the async API keeps a reference to your request (within the thread pool where async IO operations are lodged) and so it won't be garbage collected until it completes.

查看更多
唯我独甜
6楼-- · 2019-01-19 14:23

The object remains referenced just fine, by the implementation of async calls - which needs to maintain a list of all open requests, to correlate incoming data to the requests. Most likely, .NET uses a global (or class) variable to store the requests.

查看更多
登录 后发表回答