05-23-2007, 08:11 PM | #1 (permalink) |
Insane
|
[C#] Help with threads and file i/o
I hope I'll be able to delineate exactly what my problem is here. In short, I have 2 threads running side-by-side. Each thread has a file open that is being written to. The program is basically looping to try and find a prime factor (the RSA thing) and I write every nth prime to a file so as to have a backup in case of a crash or needing/wanting to shut down the program.
The problem is, the factors don't seem to write to the files unless it's closed properly (I don't understand this). So, I need to either find a way to close the file by pressing Ctrl+C or something, or I need to find a way to force the factors to be written. I doubt I've explained the problem properly, but feel free to ask questions about it. |
05-23-2007, 11:30 PM | #2 (permalink) |
Tilted
Location: Orlando, FL
|
I think it may be that I/O is buffered so as to not drag down performance of the system if it had to keep writing often to the disk. First, how often are things written to the file. Second, there may be a way to force the write to occur...I think this may be your issue, and I think I've faced it before. I'll try to get back to you about it, or hopefully someone else has the answer already.
I guess in these coding cases, posting some source code is always useful if possible. |
05-24-2007, 09:09 AM | #4 (permalink) |
Lover - Protector - Teacher
Location: Seattle, WA
|
How are you opening the file? And how do you know that both threads won't write to the same file simultaneously, thereby overwriting the other's work? This is a classical shared resource problem, and it's typically solved by busy waiting. Perform each calculation in the thread, but only allow a thread to open the file if it exists and is closed. If it's not closed, sleep until it opens. Once it's open, immediately write the data and close the file.
If you can somehow guarantee exclusive access or know that they won't be overwriting each other, make sure that you're setting the FileShare parameter when you open the file. i.e. new FileStream("Filename.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
__________________
"I'm typing on a computer of science, which is being sent by science wires to a little science server where you can access it. I'm not typing on a computer of philosophy or religion or whatever other thing you think can be used to understand the universe because they're a poor substitute in the role of understanding the universe which exists independent from ourselves." - Willravel |
05-24-2007, 10:40 AM | #5 (permalink) |
Insane
|
I have 2 separate files opened (csharplow.txt and csharphigh.txt). If I delete these two files before I run the program, they're created. I have also added a if(File.Exists()) for each one every time something is supposed to be written to either file, and the system recognizes that the file is there.
I'm using StreamWriter for each file (streamwriters are sw1 and sw2). |
05-24-2007, 11:05 AM | #6 (permalink) |
Lover - Protector - Teacher
Location: Seattle, WA
|
Oh I think I see what you're saying now.. you want a way to terminate without loss of data?
PHP Code:
Do your calculations, start your threads, etc.. then PHP Code:
__________________
"I'm typing on a computer of science, which is being sent by science wires to a little science server where you can access it. I'm not typing on a computer of philosophy or religion or whatever other thing you think can be used to understand the universe because they're a poor substitute in the role of understanding the universe which exists independent from ourselves." - Willravel |
05-24-2007, 01:02 PM | #8 (permalink) |
Crazy
Location: Atlanta
|
You have to flush the streamwriter. The OS determines when buffered writes actually make it to disk. When object is destroyed it forces a flush.
The stream writer has a function Flush() that will do it for you. It can be bad on performance but you can explicitly call Flush every time you write something.
__________________
A clear conscience is usually the sign of a bad memory. |
05-29-2007, 06:33 AM | #10 (permalink) |
Tilted
Location: Ontario, Canada
|
I think from my experience the best way to deal with objects like this is to use the "using" operator when opening/closing he objects. By using "using", it automatically calls any dispose/flush/close functions that an object might have.
The syntax is like the following: using( StreamWriter strWriter = new StreamWriter ("txtFileName.txt") ) { // do whatever you want to do with it... // } When the "using" directive is out of scope/finished, it then automatically calls any cleanup functionality. I just find it is safer to use this way, and it might even be more efficient on the system (you'll have to look that up to verify).
__________________
" Can't keep my eyes from the circling skies, Tongue-tied and twisted just an earth-bound misfit, I " Last edited by Nooze2k; 05-29-2007 at 06:36 AM.. Reason: Automerged Doublepost |
05-29-2007, 10:31 AM | #11 (permalink) |
Crazy
Location: Atlanta
|
wombatman, glad to help. The performance issues with dynamically calling flush will not always be noticeable. If the OS is idle it will not have any impact but if its busy and you interupt it to force a flush it can be noticeable.
Nooze2k, that is the best way of handling the situation if you can limit the scope fo the streamwriter but it sounds like he wants to keep it open. Constantly opening and disposing the the streamwriter would be hell on performance.
__________________
A clear conscience is usually the sign of a bad memory. |
Tags |
file, i or o, threads |
|
|