Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

reuse of a closed TextWriter in multi-threading application

Status
Not open for further replies.

mepopa

Programmer
Aug 10, 2005
2
CY
I'd like to know a way to avoid the exception bellow
---------------------------------------------------------
System.IndexOutOfRangeException: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.

Server stack trace:
at System.Buffer.InternalBlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)
at System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count)
at System.IO.TextWriter.WriteLine(String value)
...
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

----------------------------------------------


And this is generated while the multi-threading application tries to reuse a closed TextWriter object.
Please notice that i've used a synchronized TextWriter wrapper for StreamWriter object for the second test.
---------------------------------------------
System.ObjectDisposedException: Cannot write to a closed TextWriter.

Server stack trace:
at System.IO.__Error.WriterClosed()
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count)
at System.IO.TextWriter.WriteLine(String value)
at RemoteObject.DebugLogger.ExceptionLog(String aLogMessage)
at RemoteObject.DataAccessObject.ExecuteSQL(String aFuncName, ArrayList aParameterList, DataSet& aDataset)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
...
-------------------------------------------------
 
Two things:
1. You need a way to tell the other threads that the TextWriter is closed, so they don't try and use it. The Interlocked class can help with this.

2. You need a way to synchronize your writes, so that two or more threads don't try and write to the Writer at the same time. You'll want to wrap access to your writer in a class, and protect the write method by using the C# lock keyword.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Hi Chip,
Thanks for your answer. As i've said, i've tried to use a wrapper class to synchronize the writer access. The problem is that sometimes (not very often) i need to close the writer in a thread, but also, to continue to use it in another thread.
What I'd like to know is :
1) how to check that the textwriter is closed!
2) if so, how to reopen (reinitialize with the filename) the textwriter object!
Thanks
 
You need a thread-safe way to talk between your threads. Looking at a TextWriter.IsClosed property (there isn't one anyway) in each thread is not safe because they're not atomic operations. You can use the lock keyword for this:
Code:
object closedflag = new object();
bool IsClosed;
:
:
// Prior to writing
lock(closedflag)
{
  if (IsClosed)
    return;
}

When closing:
lock(closedflag)
{
  mytextwriter.close
  IsClosed = true;
}
This isn't the most efficient code in the world, but it ought to sortof work.

Also, look at the static Synchronized method on the TextWriter.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top