开发者

Can running object be garbage collected?

开发者 https://www.devze.com 2022-12-28 13:47 出处:网络
I have a simple class: public class Runner { public void RunAndForget(RunDelegate method) { ThreadPool.QueueUserWorkItem(new WaitCallback(Run), method);

I have a simple class:

public class Runner
{
    public void RunAndForget(RunDelegate method)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(Run), method);
    }

    private void Run(object o)
    {
        ((RunDelegate )o).Invoke();
    }
}

And if I use this like so:

private void RunSomethingASync()
{
    Runner runner = new Runner();
    runner.Fi开发者_开发问答reAndForget(new RunDelegate(Something));
}

Is there any danger using it like this? My C++ guts tell me that runner object should be destroyed after RunSomethingASync is finished. Am I right? What happens then to the method running on different thread?

Or perhaps it is other way around and runner will not be collected? That would be a problem considering I may call RunSomethingASync() many times.


My C++ guts tell me that runner object should be destroyed after RunSomethingASync is finished. Am I right?

In short, no. .NET garbage collection is not done on a deterministic basis. An object is eligible for garbage collection once it is no longer rooted - that is, once no more reference paths to it (from living objects) exist. There is no guarantee that any particular object -- or, indeed, any object at all -- will ever be garbage collected, though it's pretty likely.

However, in your case, your object isn't even eligible. While the object is falling out of scope in your code (so it would appear that no references exist), delegates do contain references to their owning instance (assuming they point to an instance method). A reference to your object will exist until Run is called, as the ThreadPool is holding on to a reference to the delegate until then, and that delegate has a reference to Runner.

So, to answer your question, there is no danger in what you're doing. Because the delegate references the instance, your object cannot and will not be collected until after your operation completes. Once it completes, your object will then be eligible.


The object will not be garbage collected until it is no longer rooted - that is, until all reachable references to it have been removed. There is an exception to this where if two objects hold references to each other and nothing else holds references to those objects, those two objects are available for Garbage Collection. Running asynchronous methods like yours holds references to the object and won't be disposed mid call.

A note to a comment below: Calling Dispose() on a method does not force a Garbage Collection on that object.

Since we're talking about Garbage Collection here is a link to the GC.Collect function: http://msdn.microsoft.com/en-us/library/xe0c2357.aspx

and the GC class itself:
http://msdn.microsoft.com/en-us/library/a0fwz4wc(v=VS.100).aspx

EDIT: See Adam's answer about delegates and references to objects.


No, object where's is code running can not be collected because, there is several references to the object (for example "this" is reference to the object).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号