exchange of object reference that is used along with "using" keyword

  • Thread starter Thread starter Philipp Sumi
  • Start date Start date
P

Philipp Sumi

Hello all

I have a thread that performs some simple I/O within a loop that runs on
a separate thread. I used the using keyword to ensure the writer's disposal:


using (writer)
{
while (myCondition)
{
if (buffer.Count >= this.bufferThreshold)
{
//do some I/O
}
}
}



As requirements have changed, I have to exchange my StreamWriter from
time to time which happens outside of this loop. I can easily close the
current writer and exchange the writer reference:


public void ExchangeFiles()
{
//pause I/O loop
this.Pause();

//close currently used file
writer.Close();

//replace writer reference
writer = new StreamWriter(...);

//continue I/O loop
this.Continue();
}



So far so good, but I don't know whether the using-statement that was
initialized with the original StreamReader reference still works
properly (or I'm messing things up by exchaning the reference). Unit
tests still run nicely but I would like to hear your opinion on this. I
guess I will be save with a try/finally block but if using is ok, I'll
keep the current solution.

Thanks for your advice

Philipp
 
Philipp,

From what I can see, this is bad practice, because you are unaware of
the state of the reader when you try and use it. Granted, all you are doing
is closing it (which will not be a problem), but if you were going to do
other things, then I would definitely say that this is an issue.

Also, if you are sharing the reader with other methods outside of the
using block, I would not place the reader in the using block, because then
you have to make sure that the reader is not closed, and open a new one if
you want to use it. If anything, I would just create the reader in the
local method and then use that.

Hope this helps.
 
Hello Nicholas

Thanks for the fast reply :-)


From what I can see, this is bad practice, because you are unaware of
the state of the reader when you try and use it.

As a matter of fact, I am. I only use the writer within the loop of the
thread. The only other access on the writer is the exchange and before
doing so, I'm flushing the reader and interrupting the I/O thread.

But I agree that this practice may lead to issues - especially if code
changes and I (or any other developer) do not remember the using-part if
work is done on different methods. So I'll change it anyway.


Also, if you are sharing the reader with other methods outside of the
using block, I would not place the reader in the using block

I/O only occurs within the block. The only access outside this loop is
the closing of the current log and the recreation of the writer object.
So if the using statement does not try to access the formerly created
instance, it should technically work.

....but it was rather a theoretical question as I don't know how using
works behind the scene ;-)


Still, things got clearer now - thanks!

Philipp
 
So far so good, but I don't know whether the using-statement that was
initialized with the original StreamReader reference still works
properly (or I'm messing things up by exchaning the reference). Unit
tests still run nicely but I would like to hear your opinion on this. I
guess I will be save with a try/finally block but if using is ok, I'll
keep the current solution.

Along with Nicholas's points:

The using statement creates a new stack variable, so the reference
which was used at the start of the using statement is the one which is
Disposed at the end. Here's a sample to show that:

using System;

class Test : IDisposable
{
static Test x = new Test("First");
string name;

Test(string name)
{
this.name = name;
}

public void Dispose()
{
Console.WriteLine ("Disposing of {0}", name);
}

static void Main()
{
using (x)
{
x = new Test("Second");
}
}
}
 
Back
Top