I have a static StreamWriter field for a log file I need to access through a lambda function that listens to StandardOutput on a long-running Process.
I'm using the null/not-null status of the field to determine if the Process is busy on another thread; the actions need to be performed sequentially.
My question is, what happens when I set my variable to null inside a using block? Will it still get disposed properly?
public class Service
{
private static StreamWriter logger;
void Run(string logFile)
{
using (logger = new StreamWriter(logFile))
{
/* ... */
logger = null;
}
}
}
According to the C# reference, § 8.13, your code:
private static StreamWriter logger;
using (logger = new StreamWriter(logFile))
{
/* ... */
logger = null;
}
is equivalent to
private static StreamWriter logger;
{ // using scope
logger = new StreamWriter(logFile);
IDisposable resource = logger; // hidden var inserted by the compiler
try
{
/* ... */
logger = null;
}
finally
{
if (resource != null)
resource.Dispose();
}
}
The relevant quote:
A using statement of the form
using (expression) statement
has the same three possible expansions, but in this case ResourceType is implicitly the compile-time type of the expression, and the resource variable is inaccessible in, and invisible to, the embedded statement.
This is not a problem. You'd have to look at the IL with ildasm.exe to see how the compiler does this. But it generates an extra variable to store a reference to the object so you cannot shoot your foot like this. The equivalent C# code would (roughly) look like this:
StreamWriter $temp = new StreamWriter(logFile);
logger = $temp;
try {
// etc...
logger = null;
}
finally {
if ($temp != null) $temp.Dispose();
}
That extra $temp variable keeps you out of trouble.
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