Strange behavior of several processes

I am writing two Windows console applications as shown below

class ProgramA { static void Main(string[] args) { FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(fs); TextWriter old = Console.Out; Console.SetOut(sw); Console.WriteLine("Process A Started " + DateTime.Now.ToString()); sw.Flush(); Process p = new Process(); ProcessStartInfo pi = new ProcessStartInfo(); pi.FileName = @"D:\ProgramB.exe"; p.StartInfo = pi; pi.UseShellExecute = true; pi.RedirectStandardOutput = false; bool result = p.Start(); Console.WriteLine("Process A Ended " + DateTime.Now.ToString()); sw.Flush(); } } 

and

 class ProgramB { static void Main(string[] args) { try { FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(fs); TextWriter old = Console.Out; Console.SetOut(sw); Console.WriteLine("Process B output " + DateTime.Now.ToString()); sw.Flush(); } catch (Exception e) { Console.WriteLine(e.Message); } } } 

These are completely different exe files. When I debug ProgramA step by step with F5, the result is in E: \ console.txt

Process A began on 02/26/2010 1:43:59 PM Process completed on 2/26/2010 13:44:03

But if I just started ProgramA with Ctrl + F5, the result in E: \ console.txt will be

Process exit B 2/26/2010 13:48:50 Process completed 2/26/2010 13:48:50

I'm confused. Initially, I want 2 processes to write to the same file. But after some thought, I thought that since Process A first took control of console.txt, Process B should not have access to console.txt, and the result should look like below:

Process A began on 02/26/2010 1:43:59 PM Process completed on 2/26/2010 13:44:03

when process B throws an access denied exception. But this is not so. What for? Where is the message "process begins"?


I change my code to below:

 class ProgramA { static void Main(string[] args) { FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(fs); TextWriter old = Console.Out; Console.SetOut(sw); Console.Write("aaaaa"); Console.Write("AAAAA"); sw.Flush(); Process p = new Process(); ProcessStartInfo pi = new ProcessStartInfo(); pi.FileName = @"D:\ProgramB.exe"; p.StartInfo = pi; pi.UseShellExecute = true; pi.RedirectStandardOutput = false; bool result = p.Start(); Console.Write("aaaaa"); sw.Flush(); } 

and

 class ProgramB { static void Main(string[] args) { try { FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(fs); TextWriter old = Console.Out; Console.SetOut(sw); Console.Write("bbb"); sw.Flush(); } catch (Exception e) { Console.WriteLine(e.Message); } } } 

And the contents of console.txt

bbbaaAAAAAaaaaa

Maybe this can explain something. I understand it.

Thanks.

+4
source share
2 answers

Two things:

  • firstly, since you did not use FileShare.None, both exes will have access to the file, so Process B will still be able to access the file.

  • second, since you opened the file with OpenOrCreate (and nothing more), the file will be opened, and the entries you make will begin at the beginning of the file. Try making FileStream.Seek to search to the end of the file before recording. Opening the file in FileMode.Append will not really help (if you run them in parallel), I think, since both processes will trample on each other anyway.

Even better, try making FileStream.Lock to ensure that the two processes do not trample on each other.

+1
source

try using FileMode.OpenOrCreate | FileMode.Append FileMode.OpenOrCreate | FileMode.Append in the File.Open method

+1
source

Source: https://habr.com/ru/post/1302452/


All Articles