多个进程的奇怪行为

时间:2010-02-26 05:53:59

标签: c# operating-system

我写了两个Windows控制台应用程序,如下所示

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();
    }
}

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);
        }
    }
}

它们是完全不同的exe文件。当我使用F5逐步调试ProgramA时,E:\ console.txt中的结果是

  

处理A开始于2010年2月26日13:43:59   流程A结束2/26/2010 13:44:03

但如果我只是用Ctrl + F5运行ProgramA,那么E:\ console.txt中的结果是

  

流程B输出2/26/2010 13:48:50   流程A截止日期2/26/2010 13:48:50

我很困惑。最初,我想让2进程都写入同一个文件。但经过一些反思,我认为自从进程A控制了console.txt之后,进程B应该无法访问console.txt,结果应该类似于下面的内容:

  

处理A开始于2010年2月26日13:43:59   流程A结束2/26/2010 13:44:03

使用进程B抛出访问被拒绝的异常。但事实并非如此。为什么? “Process A Started”消息在哪里?


我将代码更改为以下内容:

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();
    }

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);
        }
    }
}

console.txt的内容是

  

bbbaaAAAAAaaaaa

也许这可以解释一些事情。我正在搞清楚。

感谢。

2 个答案:

答案 0 :(得分:1)

尝试在FileMode.OpenOrCreate | FileMode.Append方法

中使用File.Open

答案 1 :(得分:1)

两件事:

  • 首先,由于您尚未使用FileShare.None,因此两个exes都可以访问该文件,因此进程B仍然可以访问该文件。

  • 第二,由于您已使用OpenOrCreate打开文件(并且没有其他内容),因此将打开该文件,并且您将从该文件的 start 开始写入。在写入之前尝试执行FileStream.Seek以寻找文件的末尾。我认为,在FileMode.Append中打开文件实际上并没有帮助(如果你并行运行它们),因为两个进程仍然会相互踩踏。

更好的是,尝试使用FileStream.Lock来确保两个进程不会相互踩踏。