I have the following lines of code:
xslt.Load(XmlReader.Create(new FileStream(#"C:\website\TransList.xslt", System.IO.FileMode.Open)));
xslt.Transform(mydoc.CreateReader(),null, sw);
It works fine, if I stop the project and launch it again, I get the following error:
[System.IO.IOException] = {"The process cannot access the file 'C:\website\TransList.xslt' because it is being used by another process."}
I then have have to goto the command line and do a IISRESET to get, I can also reset the app pool, this is easiest at this time as this is just my dev box.
Now I do have the call in a try catch statement, but I cannot access the xslt object in the handler.
The xslt object doesn't seem to have a close or dispose method.
The garbage collector never gets a shot at it , it seems.
Any ideas?
You will need to close your FileStream and Reader, either explicitly using .Close() or via a using statement:
using (FileStream fs = new FileStream(#"C:\website\TransList.xslt", System.IO.FileMode.Open))
{
xslt.Load(XmlReader.Create(fs));
using (var reader = mydoc.CreateReader())
{
xslt.Transform(reader, null, sw);
}
}
There is no need to explicitly create a FileStream and an XmlReader, if you know the file location then you can simply pass that to the Load method, using this overload:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(#"C:\website\Translist.xslt");
If you think you need to create a FileStream and an XmlReader then I agree with the suggestions already made, use the 'using' statement to properly close and dispose of those objects.
Filestream implements IDisposable and requires you to invoke Dispose to release external resources as well as implicit;y invoke close(). You should wrap your instantiation of Filestream in a using block as it ensures Dispose is invoked even if an exception is raised. To answer your question though, since you did not close the filestream, your process, presumably the w3wp.exe process still has a handle on the file stream and the only way you can release is it to reset iis or recycle the app pool. For future reference, just wrap the filestream in a using block to be safe.
Related
I have a StreamWriter which underlying stream is a FileStream. Will the following code guarantee that the FileStream also flushes its buffer into the actual file on the file system, or do I need to explicitly call Flush() on the FileStream?
using (var fs = new FileStream("blabla", FileMode.Append)) {
using (var sw = new StreamWriter(fs)) {
sw.WriteLine("Hello, I want to be flushed.");
sw.Flush(); //I need this to also flush onto the file, not just to the FileStream
}
}
As per MSDN, "Flushing the stream will not flush its underlying encoder unless you explicitly call Flush or Close", but I do not know if a FileStream can be considered an "underlying encoder".
Also, if I don't specify FileOptions.WriteThrough, am I guaranteed that the OS will eventually write the flushed line onto the disk even if the program crashes before the two streams have been closed (assuming for example no using {} blocks, only a call to Flush())?
In my scenario I need to leave the stream open (for logging) so I cannot use using {} blocks, but I would like to make sure data will always be written to the disk even if the program crashes. I can afford to lose data if there is a power shutdown and the OS has not flushed onto the disk, but otherwise I need the OS to eventually flush even if I never properly call Close() on the stream.
Yes, calling Flush on StreamWriter will cause the underlying stream to be Flushed. The 4.5 version calls a private Flush(bool,bool) function, which ends with:
if (flushStream)
{
this.stream.Flush();
}
Where flushStream is the first parameter, this.stream is the stream that the StreamWriter was constructed on, and the call in Flush() is Flush(true,true).
(Older parts of answer - I was being very roundabout in answering. Moved most relevant part of answer to top)
It's not explicitly spelled out in the documentation anywhere I can find it, but any stream class that is constructed by passing it another stream should be assumed to "take ownership" of that stream (unless it's specifically called out otherwise).
That is, once you've constructed the StreamWriter using fs, you shouldn't perform any direct actions on fs yourself.
The part you quoted from MSDN relates to the later sentences:
This allows the encoder to keep its state (partial characters) so that it can encode the next block of characters correctly. This scenario affects UTF8 and UTF7 where certain characters can only be encoded after the encoder receives the adjacent character or characters.
That is, you may have passed data to Write such that you've given it some Unicode surrogates, but not a complete character. Flush will not write those surrogates to the stream. So long as you're always passing well formed (complete) strings to Write, you do not need to concern yourself about this.
Streams disposal is guaranteed if used with using block!
With a chain of streams,closing the outermost stream(at the head of the chain) i.e StreamWriter in your case closes the whole lot i.e FileStream
Flush method forces internal buffer to be written immediately.Flush is automatically called when stream is closed,so you never need to do the following
s.Flush();s.Close();
So,the moment the most topmost stream is closed it flushes and then closes it underlying streams who also flush there content.
For example consider this chain
FileStream->GZipStream->StreamWriter
So,the moment you close the StreamWriter
StreamWriter flushes and closes.It also closes undelying GZipStream
GzipStream flushes and closes.It also closes underlying FileStream
FileStream flushes and closes
I want to create a file ONLY if it doesn't already exists.
A code like:
if (!File.Exists(fileName))
{
fileStream fs = File.Create(fileName);
}
Leave it open for a race-condition in case the file will be created between the "if" to the "create".
How can I avoid it?
EDIT:
locks can't be used here because it's a different processes (multiple instances of the same application).
You can also use
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
However, you should look into thread locking as if more than one thread tries to access the file you'll probably get an exception.
Kristian Fenn answer was almost what I needed, just with a different FileMode. This is what I was looking for:
FileStream fs = new FileStream(fileName, FileMode.CreateNew);
Is this not a better solution. Also notice the using(var stream...) Use it to close the stream to avoid IO Exceptions.
if (!File.Exists(filePath))
{
using (var stream = File.Create(filePath)) { }
}
If the contending attempts to create the file are in the same process, you can use a lock statement around your code to prevent contention.
If not, you may occasionally get an exception when you call File.Create. Just appropriately handle that exception. Checking whether the file exists before creating is probably advisable even if you are handling an exception when the file does exist because a thrown exception is relatively expensive. It would not be advisable only if the probability of the race condition is low.
First you Lock or Monitor.Enter or TryEnter APIs to lock the portion of the code.
Second you can use FileStream API with FileMode.OpenOrCreate API. If the file exists, it just uses it or else it just creates it.
If I have the following code:
FileStream fs = new FileStream(...);
TextWriter tw = new StreamWriter(fs);
Am I supposed to call only tw.Close(), or fs.Close() as well? I'm using the TextWriter persistently throughout an application, so I can't just wrap it in a Using(...) block, since I need to be able to use it at multiple points.
Otherwise, I would just write it as:
using (FileStream fs = new FileStream(...))
{
using (TextWriter tw = new StreamWriter(fs))
{
// do stuff
}
}
And avoid the issue at all together. But, I don't really know what to do in this circumstance. Do I close tw, fs, or both?
Also, more generally: If I compose multiple streams together, such as C(B(A)), can I call Close / Dispose on C and then not worry about having to call it on B and A?
You only need to close the StreamWriter.
From the documentation of the StreamWriter.Close method:
Closes the current StreamWriter object
and the underlying stream.
Also notable in the documentation of the method:
This implementation of Close calls the
Dispose method passing a true value.
This means that closing and disposing the StreamWriter are equivalent. You don't have to dispose the object after closing it, or close it before disposing it. The FileStream.Close method does the same, so closing or disposing the StreamWriter will also dispose the stream.
If you wouldn't be able to find information like this for a class, you can always dispose both the writer and the stream to be safe. Disposing an object that has already been disposed does not cause any problem, and the method would just do nothing. Just make sure to close them in the right order, i.e. closing the writer before the stream.
Because you have already enclosed your stream declaration in a "using" statement you to not need to specifically do either. Using invokes dispose and the dispose invokes close.
See this article from SO
You're safe to Dispose() both tw and fs. If tw does happen to Dispose() the underlying stream, calling Dispose() again will be a no-op.
Update: Now I see the real question... In your case, I would turn to ILSpy which shows that TextWriter.Dispose() does indeed call Close() on the underlying stream. So you're fine to just call tw.Dispose().
I open a FileStream with FileMode.Open and FileAccess.Read. Shortly after that I call a function to handle the file's contents. I use Invoke to make the call because the call comes from a Thread and the function has to put the results on a Form. The function accepts any kind of Stream (I call it with MemoryStreams too without a problem) and uses XmlTextReader to read the XML in the FileStream, but on rare occasions for unknown reasons even the first Read() throws an ObjectDisposedException and the stream's CanRead property returns false if the stream was already closed.
In the Thread the FileStream is a local using variable, so I don't think another threads should be able to close it, and I don't close it until the Invoke returned. There are no Exceptions thrown so the file is definetly there (since there is no FileNotFoundException) and should be accessed properly (since there is no UnauthorizedAccessException and IOException).
How could my FileStream still look closed sometimes just after opened?
(It might matter that I'm running my code on a Windows CE 5 device with Compact Framework 3.5 and I wasn't able to reproduce the same behaviour on my desktop PC with XP yet.)
EDIT:
I know, that this Invoke is ugly but that alone can't be a reason to fail, can it? (And, in most of the cases it doesn't fail at all.)
//the code in the thread
//...
using (FileStream fs = File.Open(assemblyPath + "\\white.xml", FileMode.Open, FileAccess.Read))
{
mainForm.Instance.Invoke(new DataHandler(mainForm.Instance.handleData), new object[] { fs });
}
//...
//and the handler
public void handleData(Stream stream)
{
infoPanel.SuspendLayout();
try
{
using (XmlTextReader xml = new XmlTextReader(stream))
{
//it doesn't matter what is here
}
}
catch{}
}
There's one reason I can think of: the worker thread got aborted. This will run the finally block generated by the using statement and close the file. How it could be aborted is a secondary question. Is the thread's IsBackground property set to true? Is the program bombing on an unhandled exception elsewhere and shutting down? Just guesses of course.
Sure, this is expected behavior. You call Invoke, which marshals the call to another thread. The calling thread then continues to run and the using block exits, calling Dispose on the stream. This Dispose is happening before you are done (and maybe before you start) using the stream in the UI thread. The exact timing of these actions is going to depend on processor load and some other factors, but it's certainly unsafe.
Either don't put the stream in a using block or better yet have the thread do the read and pass the results to the UI via Invoke.
EDIT
As Hans points out in the comment, the above explanation should be for a BeginInvoke call, which underneath calls PostMessage. Invoke, on the other hand, uses SendMessage. Both propbably uses some WM_COPYDATA shenanigans (I've not looked to see) to marshal the data.
The Invoke call should be executing the entire handler you have posted, though the behavior you see indicates otherwise. From the code you posted there's no real way for us to determine what is closing the stream.
I would still refactor what you've done here because right now you're tying up both the UI and worker threads with the reader operation. I'd do the read work in the worker thread and then pass the results to the UI. This would decrease the odds of the reader work causing UI choppiness and would eliminate the possibility of the stream getting closed while you're reading from it.
I saw the same issue on some embedded board (ARM) I'm working on. Then I created a little test.
The following code (not involving any Threads!) crashes:
using (var w = new StreamWriter(File.Create("file.txt"), System.Text.Encoding.UTF8))
{
for (int i = 0; i < 1000; i++)
{
w.WriteLine("Test");
}
}
This code however does not crash:
using (var w = File.CreateText("file.txt"))
{
for (int i = 0; i < 1000; i++)
{
w.WriteLine("Test");
}
}
So, my guess can only be that the underlying native code treats text files differently than when you open the file using File.Create(). Both files are then written in UTF-8, so there is no difference about the encoding.
BTW: sorry I'm one year late on the answer, but I hope it'll help somebody
I have this open-source library that I'm having some trouble fixing a problem... This library allows to easily create an XML file to store application settings. But I'm having an issue saving the changes.
I have another application where I'm using this library and every time that application window is done resizing, I call the Save() method of the library to save the window size/position to the XML file.
Most of times it works fine, everything is saved. Once in a while though, I get an exception saying the file is being used by another process.
I really need to make sure that changes are saved every time the Save() method is called, I need to handle this exception somehow or prevent it from happening.
What are you guys suggestions for best handling this situation?
The code for the Save() method is the following:
public void Save() {
// Create a new XML file if there's no root element
if(xDocument.DocumentElement == null) {
xDocument = new XmlDocument();
xDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
"<" + XmlRootElement + ">\n</" + XmlRootElement + ">");
}
// OMITTED CODE WAS HERE (NOT IMPORTANT FOR THE PROBLEM)
// Create a new XML writer for the XML file
XmlWriter xWriter = XmlWriter.Create(XmlFilePath, new XmlWriterSettings() {
Indent = true,
IndentChars = "\t"
});
// Sort the XML file using the XSL sylesheet and save it
xslTransform.Transform(xDocument, xWriter);
// Clear the buffer and close the XML writer stream
xWriter.Flush();
xWriter.Close();
}
XmlWriter is IDisposable. You should wrap it in a using() clause.
http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx
I have to go with a combination of the answers already given here.
Your XmlWriter should be in a using block for several reasons. You should dispose it so that your resources are freed as soon as possible. Also, what if you throw an exception while interacting with it. The file wouldn't be closed properly, at least until the finalizer kicks in and frees your resources.
Even with the using statement, you "might" have contention on the file and need to place the Save code in a lock statement. The method is non-reentrant by nature because the file is a shared resource. Putting a lock around it might be over kill if you don't have multiple threads, but you would ensure that you properly controlled access to the file.
The other thing to consider is that you might want to move the saving operation to a background thread to write the file out. If you get a large settings file you might cause strange UI interactions because you are waiting on the file to write every time the user resizes and this happens on the UI thread. If you did this you would definitely need to lock access to the file resource.
It could be the case that the window-resizing-completed events are firing so quickly, that the save function is being called, the called again before it finishes running the first time. This would result in the error you're describing (the other process using the file is... YOU!). Try surrounding your code with a lock, thusly:
lock(some_shared_object)
{
//Your code here
}
Also you might try using a lock statement. It could be that the methods are overrunning one another.