smwikipedia
smwikipedia

Reputation: 64205

Strange behavior of Multiple Processes

I write two windows console application as 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);
        }
    }
}

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

Process A Started 2/26/2010 13:43:59 Process A Ended 2/26/2010 13:44:03

But if I just run ProgramA with Ctrl+F5, the result in E:\console.txt is

Process B output 2/26/2010 13:48:50 Process A Ended 2/26/2010 13:48:50

I am confused. Originally, I want to have the 2 process both write to the same file. But after some reflection, I thought since Process A has taken control of the console.txt first, Process B shouldn't be able to have access to console.txt, and the result should be similar to below:

Process A Started 2/26/2010 13:43:59 Process A Ended 2/26/2010 13:44:03

with Process B throw an access denied exception. But it's not. Why? Where is the "Process A Started" message?


I change my code to the 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 content of console.txt is

bbbaaAAAAAaaaaa

Maybe this could explain something. I am figuring it out.

Thanks.

Upvotes: 4

Views: 471

Answers (2)

Aryabhatta
Aryabhatta

Reputation:

Two things:

  • first, since you have not used FileShare.None, both exes will have access to the file, so Process B can still access the file.

  • second, since you have opened the file with OpenOrCreate (and nothing else), the file will be opened and writes you do will be from the start of the file. Try doing a FileStream.Seek to seek to the end of the file before writing. Opening the file in FileMode.Append won't really help (if you run them in parallel), I think, as both processes will still trample on each other.

Better yet, try doing a FileStream.Lock to ensure the two processes don't trample on each other.

Upvotes: 1

Adeel
Adeel

Reputation: 19228

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

Upvotes: 1

Related Questions