Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have some doubts regarding the using statement:

I have a class called

MyJob which is Disposable. Then i also have a property on MyJob JobResults that is also Disposable.

MY code:

using (MyJob job = new MyJob())
{
    //do something. 
     FormatResults(job.JobResults)
}

public string FormatResuls(JobResuts results)
{
}

MY First question is: In this case after the using block are both MyJob and MyJob.Results disposed or only MyJob and NOT MyJob.Results?

I am also performing parallel processing w.r.t Tasks in C#:

Tasks allTasks = List<Tasks>

try
{
   foreach(Task t in allTasks)
   {
         // Each tasks makes use of an IDisposable object.
        t.Start();
   }
    Task.WaitAll(allTasks);
}
catch(AggregateExecption aex)
{
    /// How do I ensure that all IDisposables are disposed properly if     an exception happens in any of the tasks?
}

My second q, in the code above, what is the proper way to ensure to dispose off objects correctly when handling exceptions in tasks?

Sorry if my questions are too naive or confusing, as i am still trying to learn and understand C#. Thanks guys!

share|improve this question
8  
1. Your are asking two questions in one - it is actually not a recommended format on Stack Overflow. 2. About first question - we do not know how your class is designed. Or are you asking whether you should dispose nested object or not? –  Eugene Podskal 5 hours ago
1  
It depends on how your class MyJob implements IDisposable.. –  Spencer Waz 5 hours ago
    
It depends on how your class MyJob implements IDisposable.. Be sure you are following the correct pattern... link –  Spencer Waz 4 hours ago
    
    
I may be wrong, but I'm pretty sure there's no additional magic behind the using statement apart from being so called "syntactic sugar" that calls IDisposable.Dispose on the parameter after executing the enclosed code block. –  Grx70 4 hours ago

5 Answers 5

up vote 4 down vote accepted

are both MyJob and MyJob.Results disposed or only MyJob and NOT MyJob.Results?

That is subjective to the implementation of your Dispose method. As we haven't seen it in your question, I'll assume that you aren't currently disposing your Result property in MyJob.Dispose, hence it will be the latter.

As only MyJob is wrapped in a using statement, and again assuming it does nothing to your Result property, it will be disposed as opposed to Results, which isn't wrapped in a using statement.

You could decide that MyJob, as it encapsulates your Result property, is responsible for the disposable of it as well. If you decide so, you can dispose Results in MyJobs.Dispose.

what is the proper way to ensure to dispose off objects correctly when handling exceptions in tasks?

If the delegate which is passed to the Task is wrapped in a using statement, you are safe, since using will transform your code to a try-finally block, if an exception occurs in your using block, the finally block will still run yourObject.Dispose.

share|improve this answer
    
As the other answers say, if he calls Results.Dispose in the MyJob.Dispose method, then it will in fact be disposed, so the top part is only true if he doesn't explicitly dispose it in the MyJob object. –  Ron Beyer 4 hours ago
    
@RonBeyer You're right, I edited my answer just as you posted the comment :) –  Yuval Itzchakov 4 hours ago
    
I don't think that "you could decide" is the right wording. The pattern states pretty clearly that in the various Dispose() methods you have to dispose of disposable resources, meaning that MyJob must dispose of any JobResult it has (in a has-a relationship). There's no room for interpretation whatsoever in the actual documentation. –  pid 4 hours ago
    
@pid You're a programmer, and there is always room for self-interpretation. While you're right that it is the recommended approach, there is no one way to implement something, and his use-case may not fit the "has-a" relationship, so let's dispose of it. For example, take a look at stream wrappers, such as GZipStream, which accepts a bool to indicate whether to dispose the underlying stream, or leave it open. –  Yuval Itzchakov 4 hours ago

MY First question is: In this case after the using block are both MyJob and MyJob.Results disposed or only MyJob and NOT MyJob.Results?

There is no guarantee that either objects will be disposed of immediately. The garbage collector will perform a cleanup and release the memory when it has determined the object (and references) are not being used.

My second q, in the code above, what is the proper way to ensure to dispose off objects correctly when handling exceptions in tasks?

Wrapping it in the using statement, this ensures that Dispose is invoked even if an exception is thrown.

The compiler will translate the using into a try/finally statement:

   try {
      statement;
   }
   finally {
      ((IDisposable)resource).Dispose();
   }

https://msdn.microsoft.com/en-us/library/yh598w02.aspx

share|improve this answer
1  
I think that by disposed he means "Run my Dispose method", not garbage collected. –  Yuval Itzchakov 4 hours ago
1  
"There is no guarantee that either objects will be disposed of immediately" In a using statement the Dispose method is called after the block is left –  stefan.s 4 hours ago
    
@stefan.s - yes the Dispose is immediately invoked, however the the cleanup may not be performed at that point, the framework will determine when the GC performs the cleanup. –  Darren Davies 4 hours ago
    
-1 He didn't ask about garbage cleanup, he asked if they are both disposed immediately. The answer is, yes, MyJob is disposed immediately, and whether MyJob.Results is disposed is subject to the MyJob.Dispose() implementation (if Dispose() is properly implemented, Results.Dispose() should be called) –  BlueRaja - Danny Pflughoeft 1 hour ago

Only MyJobs is disposed. For other properties, you need to understand object ownership: who owns the object should be responsible (in general) to dispose of it. A property implementing IDisposable could be used by other instances, so you can only dispose of it if you are the one who created it and there no other references to it, or the class fails gracefully if it knows that it has been disposed of.

share|improve this answer

There are a lot of good answers here but one thing remains. If you want to be assured that your object is properly disposed because it uses unmanaged resources, you should implement a destructor in your object, like:

class MyJob : IDisposable 
{
     private bool _disposed = false;
     protected virtual void Dispose(bool disposing)
     {
          if (!_disposed)
          {
              //Dispose unmanaged resources and any child disposables here
          }
     }

     void Dispose()
     {
          this.Dispose(true);
          GC.SuppressFinalize(this);
     }

     ~MyJob()
     {
          //ONLY use if you have unmanaged resources that DO NOT
          //implement their own finalizers.
          Dispose();
     }
}

However, it is recommended that you DO NOT use a finalizer (destructor) unless you are finalizing a type with unmanaged resources that does not include its own finalizer.

See https://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx for best practices on implementing IDisposable.

share|improve this answer
    
Two things. First, I wouldn't recommend implementing a finalizer, especially when we don't know from the OP's question whether these are un-managed resources. Second of all, even if you do end up implementing a finalizer, you should call GC.SuppressFinalizer(this) inside your Dispose(bool disposing) method. –  Yuval Itzchakov 4 hours ago
    
@YuvalItzchakov I edited to include the suppress finalize call, I missed it. I said below the post not to implement it unless some specific conditions are met, and the MSDN link shows a lot of good practices when implementing it. I was just showing a complete example assuming unmanaged resources without their own finalizers. –  Ron Beyer 4 hours ago
    
Don't get me wrong, I don't disagree about the finalizer issue, it is important to know that such a thing exists. I'm just saying that given the small amount of detail in the question, I wouldn't run off implementing a finalizer :) –  Yuval Itzchakov 4 hours ago

1) The best way is to dispose JobResults inside of MyJob's Dispose() methode. Otherwise it's not disposed on it's own

2) I would implement the finally part, go through every object and dispose it. But in most cases you donät need to do that read this

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.