2

using declarations were just introduced in C# 8.0 but they don't behave the same as using blocks, or so i think.

The following nested using block works fine:

using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey))
using (var file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
    resource?.CopyTo(file);
}

But when i convert to a using declaration as follows, i get an IOException which says the file is being used by another process:

using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
resource?.CopyTo(file);

I want to understand what's different and how\when to use the new using declaration?

3
  • Use it any time you are working with an object that implements IDisposable and you do not plan on disposing it yourself. Commented Jul 24, 2019 at 4:41
  • Is it possible that the file pointed to by path is actually open in another process? Word and Excel are very good at setting exclusive locks on files. It could even be your own process if you are calling both statement blocks within Tasks or async. Commented Jul 24, 2019 at 4:42
  • @AlwaysLearning That's not the case, the first using statement runs ok. It only throws and exception when i use a declaration instead. Commented Jul 24, 2019 at 4:49

1 Answer 1

5

Both using declaration differ in the way they resolve scope. Old Using used to define its own scope using the curly braces,

using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
using (var file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
    resource?.CopyTo(file);
}

Here both resource and file will be disposed the moment the closing braces are found.

With, The new declaration if you haven,t defined a scope like the above, It will automatically attach to the nearest scope,

void certainMethod()
{
   using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
   using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
   resource?.CopyTo(file);
}

Here when the method call to certainMethod ends, Dispose for resource and file will be called.

Edit: To your case, There shouln't be any issue if your code is doing just this, But if there are two of such blocks, First one will work but second will fail, Example,

 void certainMethod()
    {
       using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
       using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
       resource?.CopyTo(file);
       using var oneMoreFile = new FileStream(path, FileMode.Create, FileAccess.Write);
       //This will fail
       resource?.CopyTo(oneMoreFile );

    }
Sign up to request clarification or add additional context in comments.

3 Comments

So, basically, using declarations starts disposing at the end of the nearest block if i don't explicitly wrap them in one?
yes that's correct, It can be even an if block or a loop block.
Added an example of failure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.