0

Are there guarantees in C# that the using statement won`t inherit the try + finally combinations issues?

The question naturally follows the discussion from other here.

According to the documentation:

using (var font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}

The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object):

{
  var font1 = new Font("Arial", 10.0f);
  try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
}

So, are there any guarantees that the finally for the .Dispose will be called all the time in C#? In case it is so, does that mean that the using will actually expand to something different from just the try + catch combination?

UPDATE

In a nutshell what the question is all about. There is a known issue which discourages the use of the try + finally combination. The issue is discussed here. In the question I am asking whether or not the issue applies to the using, since the using is the same as the try + catch combination (according to the documentation linked above).

qqqqqqq
  • 1,831
  • 1
  • 18
  • 48
  • 1
    I expect it will have the same limitation, so if you need to handle that, you'd need to wrap the `using` in a `try`/`finally` (but I don't know for certain) – Rufus L Feb 10 '20 at 21:50
  • 3
    it doesn't matter, if you don't handle it, your app is about to exit and will be cleaned up. – Keith Nicholas Feb 10 '20 at 21:51
  • @RufusL, what limitation are you talking about? The only limitation I am aware about is that the combination try + finally should always include the catch block, meaning that the try + finally should never happen, while the try+ catch + finally should be used. But I am not sure how to add the catch block into the using statement. – qqqqqqq Feb 10 '20 at 21:52
  • Some exceptions (e.g. StackOverflowException) simply cannot be recovered from. In such cases I would not expect the Dispose to run, but like Keith said, it won't matter then. –  Feb 10 '20 at 21:53
  • 1
    Your link has the answer to your question, why are you posting the same question? – Train Feb 10 '20 at 21:53
  • 2
    I don't get what you're asking. If you need a catch block, then implement one. If not, don't. – mason Feb 10 '20 at 21:53
  • @KeithNicholas, what if I opened a resource on a different server? And it is developed in such a way that it can only be closed explicitly? That is just single example of when it is useful to have a control over the exceptions in an app. – qqqqqqq Feb 10 '20 at 21:53
  • Does this answer your question? [Why finally block may not execute when exception is thrown?](https://stackoverflow.com/questions/60158238/why-finally-block-may-not-execute-when-exception-is-thrown) – Train Feb 10 '20 at 21:54
  • I'm talking about the situation from your other question, where you have other code that must run in the `finally` block. Since you don't have control over the `finally` block that the `using` generates, you'd have to add your own `try/finally` around the `using` – Rufus L Feb 10 '20 at 21:54
  • Yes, the Dispose method will be called on the object that the using block is created for, barring some extremely exceptional cirumstance (that a finally block wouldn't prevent either) such as a StackOverflowException or AccessViolationException. – mason Feb 10 '20 at 21:55
  • Using block is like a `try-finally` with `dispose()` without the exception hanlding, it's basically the same. – Train Feb 10 '20 at 21:57
  • 1
    @qqqqqqq then if you DON'T have at least a top level exception handler, you have a bug. Either way your application is exiting. If you had such a contrived situation you have MUCH bigger problems as there are various ways to kill an app without it having a chance to clean up. – Keith Nicholas Feb 10 '20 at 21:57
  • The documentation itself [covers this](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement): `The using statement ensures that Dispose is called even if an exception occurs within the using block. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.` – mason Feb 10 '20 at 21:59
  • Found a perfect duplicate: https://stackoverflow.com/a/47153949/717732 (and a good answer, with some rationale by Eric Lippert) – quetzalcoatl Feb 10 '20 at 22:01
  • @qqqqqqq good question, not many dig into this level of detail (and sometimes get caught out by it!) – Keith Nicholas Feb 10 '20 at 22:04
  • The _[known issue](https://stackoverflow.com/a/60158325/585968)_ you mentioned is referring to _"**unhandled exceptions**"_, situations in which your application should be gracefully **exiting** in your `unhandled exception handler`. Any memory, unmanaged resources and GDI objects will be **automatically released** by Windows when your process exits anyway. More importantly, you should never attempt to continue your app when you encounter a unhandled exception because your app is in an unkown state. So there is no problem. –  Feb 10 '20 at 22:06
  • Thank you everyone for helping me out. – qqqqqqq Feb 10 '20 at 22:07

0 Answers0