Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Wow. What the... This is the most bizarre piece of code I've ever seen. @.@</p> <p>First of all, what finalizer call are you referring to? The only finalizer I see is the finalizer for the <code>FinaliserObject</code>, which will be called 10,000 times, and can be called independently of whatever's going on on the static collection. I.E. yes, those objects can be destroyed while other objects are being dequeued from the collection. This isn't an issue.</p> <p>The static collection itself won't be cleaned up until the app itself exits.</p> <p>Keep in mind that there's <em>absolutely</em> no guarantee when or if those finalizers will be called before the app itself exits. Your static collection could be completely empty when you exit.</p> <p>Worse, you're assigning <code>itemValueOut</code> to whatever the last value you pull out of the queue is... which is NOT the number of items created, as you imply in your WriteLine(). Because those destructors are called in any possible order, you could theoretically add to the queue 10,000, 9,999, 9,998, ... 2, 1, in that order. </p> <p>Which is further an issue, because you're removing from the queue 10,000 times, but on the last loop, it's very possible there won't be an object to dequeue, in which case you're guaranteed to get -1 for the number of items returned (even if the other 9,999 items worked successfully).</p> <p>To answer your question, this code cannot deadlock. A deadlock would happen if <code>AddItem()</code> called <code>TryGetItem()</code>, but those locks are pretty much guaranteed to keep each other out of the static collection while adding or removing items.</p> <p>Where you're tempting fate is that you can exit your app without all of the <code>FinaliserObject</code>s having added themselves to the queue. Meaning one of the finalizers could fire and try to add to the <code>FinaliserCollection</code>, but the <code>FinaliserCollection</code> has already been disposed. What you're doing in the finaliser is <strong>terrible</strong>.</p> <p>But yes, a finalizer call can happen while you're calling <code>FinaliserCollection.TryGetItem()</code>. The finalizer will block and wait until <code>TryGetItem()</code> emerges from the <code>lock()</code>, at which point it will add another item. This is not an issue.</p> <p>As for the <code>sleep()</code> command, you're probably just throwing the timing of the garbage collection off. Remember, your objects won't be collected/finalized until the GC decides it needs the resources.</p> <p>Sorry for being so emphatic... I know you're just trying to test a concept but I really don't understand why you would want to do what you're trying to do in the finalizer. If there's really a legitimate goal here, doing it in the finalizer is <em>not</em> the correct answer.</p> <p><br /> <strong>Edit</strong> <br /> <br /> From what I'm reading and what Sasha is saying, no you will not have a deadlock. The finalizer thread may be blocked waiting for the lock, but the GC will not wait for the finalizer, and will thus unsuspend the threads, allowing the locks to be released.</p> <p>In any case, this is a very strong argument for why you shouldn't be making calls like this in a finalizer... the finalizer is <em>only</em> for releasing unmanaged resources. Anything else is playing roulette.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload