I found some strange Code in a old project of us, which is looking like this:
using (var removeGroupMembershipWorker = new BackgroundWorker())
{
removeGroupMembershipWorker.DoWork += (senderRGMW, eRGMW) =>
{
};
removeGroupMembershipWorker.RunWorkerAsync();
}
The Code in the Lambda is elided.
For me, the using Keyword and the lambda expression don't go well together: The Lambda has to leverage the object on a Class-Level, otherwise the code could not be called later.
But how does the using Keyword work here? The Thread obviously doesn't wait for the Async to finish, but what happens when the using block is left?
Is the using just ignored in such cases?
Edith says: Since I'm missing Raghus answer and this superb link; I add it here: http://softwareblog.alcedo.com/post/2011/12/09/Using-blocks-and-asynchronous-operations.aspx
This explains the problematic and the solution about the Topic.
The using block is syntactic sugar for a try ... finally construct in which the finally block calls the IDisposable.Dispose() method of the object. This is, of course, why the object being disposed must implement IDisposable, else you get a compile-time error.
Calling Dispose() is not the same as allowing the object to go out of scope to be garbage-collected. In particular, if code within the lambda happens to refer to removeGroupMembershipWorker by closure, the lambda could end up referring to an object that has been disposed. This scenario may or may not cause errors, depending what Dispose() actually does.
So, as you mention, the using pattern may not be the best idea here. If you do need to call Dispose() -- which you really should for any IDisposable -- you can call it directly when it would be safe to do so. What "safe to do so" means depends on your code, but in essence, Dispose() needs to be the last method called on the object (except any methods called within Dispose(), of course).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With