0

Assume we have 3 processes, they write to a specific file by order, in some cases when a process wants to write to the file the process closed (In middle of Writing), so access to file for another 2 processes is in trouble, I add a server process that control order of processes and when a process closed there is an event raised, so how can I release sources (file access) in this event when a process closed. Something like File.Release(FilePath);

Edit:

Write to File as Following:

try {
        if(!File.Exists(FilePath))
            throw new Exception("File does not Exist.");

        bool Clear = false;
        using(StreamReader sr = new StreamReader(FilePath)) {
            if(sr.ReadToEnd().Length > 1200)
                Clear = true;
            }

        if(Clear)
            using(StreamWriter sw = new StreamWriter(FilePath, false)) {
                sw.WriteLine(Text);
                sw.Flush();
        } else
            using(StreamWriter sw = new StreamWriter(FilePath, true)) {
                sw.WriteLine(Text);
                sw.Flush();
        }
} catch(Exception ex) {}
Saeid
  • 13,224
  • 32
  • 107
  • 173
  • 1
    show us the code that writes to the file. Basically, when you write to the file, you open a handle to that file with Write access permissions. No one else can write to that file. But once you finish writing, you should release the handle (usually by calling Dispose or Close or by putting the code into `using` block). – oleksii Jan 07 '12 at 14:05
  • @oleksii See the question I Update it. – Saeid Jan 07 '12 at 14:09
  • As said by Oleksii, use the keyword "using". It is implicitly meaning Idisposable which will maintain the handle and dispose it when the work is done. That's the best practice. It is used in the same way as used for database connections. – King Jan 07 '12 at 14:10
  • 2
    You shouldn't have to call `sw.Close()` or `sw.Dispose()` if you're using `using` blocks. – M.Babcock Jan 07 '12 at 14:12
  • @M.Babcock is this related to Release access file or cause any other trouble? – Saeid Jan 07 '12 at 14:13
  • using -- Idisposable. It disposes when its goes out of the using block. Never explicitly do that. It will throw an exception when you have multiple threads. – King Jan 07 '12 at 14:14
  • Well this code seems to close the handles to the file. So there should not be any problems (apart from you don't need to call Flush/Close/Dispose with `using`). Which exceptions do you get? Why if you have 3 processes this works, but when you have 2 - it doesn't? – oleksii Jan 07 '12 at 14:14
  • 1
    @Saeid - It shouldn't be causing the behavior you describe. It is just unnecessary since the `using` block will do them for you. – M.Babcock Jan 07 '12 at 14:16
  • @oleksii it is not about the number of processes, when I have more than 1 Process and one of them get the write access to file and in middle of writing suddenly closed the other processes in trouble to access the file. – Saeid Jan 07 '12 at 14:18
  • Or right, got you. Well this is expected behaviour. When one process access a file to **write**, other processes cannot get the same level of access. Otherwise it would be a mess. They might get **read** access through memory mapped files. But at any moment of time only one Process can write to a file. – oleksii Jan 07 '12 at 14:22
  • @Saeid - Are your read and writes really that simple? If so, you could benefit from using the static `File` methods (e.g. `System.IO.File.AppendText`). It won't solve your problem but you could avoid the `IDisposable` and `using` mess. – M.Babcock Jan 07 '12 at 14:23
  • My suggestion if you are having this problem of wanting multiple processes to write into a file. Then have a queue and collect your objects and write into the file asynchronously. while your server may continue to function , asynchronously the writing process will continue. – King Jan 07 '12 at 14:32
  • Multiple processes , you mean more than one binary tries to open and write at the same time ? – King Jan 07 '12 at 14:33
  • @King, not at the same time the server decide who write now and use named pipes for communicate with clients – Saeid Jan 08 '12 at 05:40
  • multiple clients writing at the same time to a single file is your problem. As said by the people above, no two process can get hold of the same file at the same time in write mode. Either it has to wait if you write large data, this time of waiting is significantly noticeable or you can collect the objects from the clients, queue them and write them actually from the server. Giving write access on a file that is on the server to the client can also be avoided. If your data is serialized , the you could use google protocol buffers into this . – King Jan 08 '12 at 07:36
  • But if there is a client already writing into the file, then server has to reject the new request. This is not what you would desire from a server application. Isn't it ? – King Jan 08 '12 at 07:42
  • @King no that's not happen ever I don't have any problem with orders of clients access and in time just one client can get access to file, but all of the answers is about using block but what happen if in the middle of using block suddenly the process closed? and some codes not running (in using block)? also using block not finished correctly? what happen to file and access to that? the process get write access and suddenly closed without release source(finished using block), can another process get write access to the file? – Saeid Jan 08 '12 at 08:09
  • If you are handling the file from the client and if the client process closes, it will of course have no handle to the file and obviously it will be free for another process to acquire a handle on it with write access. – King Jan 08 '12 at 08:12
  • @King if your saying is correct so I have not any problem, Thanks King, You are very helpful. – Saeid Jan 08 '12 at 08:14

1 Answers1

7
using System.IO;

class Program
{
    static void Main()
    {
          using (StreamWriter writer = new StreamWriter("important.txt"))
          {
                writer.Write("Word ");
                writer.WriteLine("word 2");
                writer.WriteLine("Line");
          }
    }
}

This is the example type we meant when saying use , keyword "using". Never close the streamwriter explicitly nor dispose it explicitly. using does all the magic for you. It disposes when the work is done and when you go out of this using block.

In a multi-threaded environment if you use close or dispose explicitly, the threads will have problem considering that the thread may just try to open the object while the previous thread just disposed it. you will have problems synchronizing your threads. This is the same problem that is normally faced in server applications which has multiple connections running into database. That's the reason we need to use it like this with Idisposable.

C# USING keyword - when and when not to use it?

This explains more about it.

Update: multiple clients writing at the same time to a single file is your problem. As said by the people above, no two process can get hold of the same file at the same time in write mode. Either it has to wait if you write large data, this time of waiting is significantly noticeable or you can collect the objects from the clients, queue them and write them actually from the server. Giving write access on a file that is on the server to the client can also be avoided. If your data is serialized , the you could use google protocol buffers for passing the data.

If you are handling the file from the client and if the client process is terminated mid-way, there will be no write handle to the file now and obviously it will be free for another process to acquire a handle on it with write access.

Community
  • 1
  • 1
King
  • 1,170
  • 2
  • 16
  • 33