TextWriter.Synchronized

K

Kris Erickson

Hi,

Have run into a problem with TextWriter.Synchronized where we are
logging errors. The call get the Textwriter looks like this:

return TextWriter.Synchronized(File.AppendText(filename));

Where filename is the name of the log file and there are no other
references to the filename within this or any other project. The error
occurs when no-one is on the machine, so no one is looking at the error
log. And we get this error:

The process cannot access the file
'C:\\error_logs\\ErrorLog_2007-03-30.txt' because it is being used by
another process. I assumed that threadsafe meant not only operations on
the object where threadsafe, but if access to that file was limited to
that synchronized object that there would be no kind of file contention
issues (let me state again that the only access to the logs is through
writing to the LogError function. Is there any way around this error?

The complete function is:

public static void LogError(string logMessage)
{

TextWriter fErrorLog = null;

try
{
fErrorLog =
TextWriter.Synchronized(File.AppendText(LogFilename));

// Create string to write
logMessage = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
": " + logMessage;

// Write string and close file
fErrorLog.WriteLine(logMessage);
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.ToString());
}
finally
{
if (fErrorLog != null)
{
fErrorLog.Close();
}
}

}
 
O

oscar.acostamontesde

Hi,

Have run into a problem with TextWriter.Synchronized where we are
logging errors. The call get the Textwriter looks like this:

return TextWriter.Synchronized(File.AppendText(filename));

Where filename is the name of the log file and there are no other
references to the filename within this or any other project. The error
occurs when no-one is on the machine, so no one is looking at the error
log. And we get this error:

The process cannot access the file
'C:\\error_logs\\ErrorLog_2007-03-30.txt' because it is being used by
another process. I assumed that threadsafe meant not only operations on
the object where threadsafe, but if access to that file was limited to
that synchronized object that there would be no kind of file contention
issues (let me state again that the only access to the logs is through
writing to the LogError function. Is there any way around this error?

The complete function is:

public static void LogError(string logMessage)
{

TextWriter fErrorLog = null;

try
{
fErrorLog =
TextWriter.Synchronized(File.AppendText(LogFilename));

// Create string to write
logMessage = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
": " + logMessage;

// Write string and close file
fErrorLog.WriteLine(logMessage);
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.ToString());
}
finally
{
if (fErrorLog != null)
{
fErrorLog.Close();
}
}

}

Well, try using a lock instead.

object syncObj = new Object();
lock(syncObj){
// TextWriter op here.
}

Best regards.
Oscar Acosta
 
K

Kris Erickson

Well, try using a lock instead.

object syncObj = new Object();
lock(syncObj){
// TextWriter op here.
}

Best regards.
Oscar Acosta

Thanks, but I was trying to avoid that high level of locking
granularity. I assumed that was what TextWriter.Synchronized was
written to avoid. I assumed it had some kind of queuing mechanism so
that writes got queued and where written without having to wait for
locks and such. Maybe I will crack out Dot Net Reflector and see how it
works...

Thanks,

Kris
 
L

Laura T.

The TextWriter gets to see the "file" only after you have opened it, and
when you open a file for writing, you get an exclusive acess to it.
It cannot "protect" it since it does not see it.

The line TextWriter.Synchronized(File.AppendText(filename)), creates an
StreamWriter object that opens the target file and then passes it to
TextWriter.
It's only then that TextWriter wraps around it and gives you synchronized
access to write to it. It does not know how the file was opened. Nor does it
care.
It protects only itself, not the dependent objects.

You have to synchroinize the file opening by yourself.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top