Home All Groups Group Topic Archive Search About

TextWriter.Synchronized

Author
2 Apr 2007 6:03 PM
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();
             }
         }

}

Author
3 Apr 2007 11:26 AM
oscar.acostamontesde@googlemail.com
On Apr 2, 8:03 pm, Kris Erickson <kris_nosp***@mha.ca> wrote:
Show quote
> 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
Author
3 Apr 2007 4:43 PM
Kris Erickson
oscar.acostamonte***@googlemail.com wrote:
Show quote
> On Apr 2, 8:03 pm, Kris Erickson <kris_nosp***@mha.ca> wrote:
>> 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
>

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
Author
3 Apr 2007 5:05 PM
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.

Show quote
"Kris Erickson" <kris_nospam_@mha.ca> ha scritto nel messaggio
news:%23YXmEFVdHHA.4616@TK2MSFTNGP03.phx.gbl...
> 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();
>             }
>         }
>
> }
>
>

AddThis Social Bookmark Button