如何使用 StreamWriter 避免竞争条件

How to Avoid Race Condition using StreamWriter

根据:https://msdn.microsoft.com/en-us/library/system.io.streamwriter%28v=vs.110%29.aspx,"By default, a StreamWriter is not thread safe. See TextWriter.Synchronized for a thread-safe wrapper." 所以我写了一个方法并使用 TextWriter.Synchronized 来同步我的 StreamWriter 对象:

        static void GenerateData()
    {
        string fileName = Path.Combine(directory, "filenames.txt");

        using(StreamWriter names = new StreamWriter(fileName))
        {
            // Synchronize access to names
            TextWriter.Synchronized(names);

            // Create 100,000 test files
            // Take advantage of parallelism
            Parallel.For(0, 100001, i =>
                {
                    // Generate name of test file
                    string curFile = Path.Combine(directory, String.Format("test{0}.txt", i + 1));

                    // Store test file name in filenames.txt
                    names.WriteLine(curFile);

                    using(StreamWriter writer = new StreamWriter(curFile))
                    {
                        // Take advantage of multiple cores
                        //TextWriter.Synchronized(writer);

                        // For 30 lines ..
                        for(int j = 0; j < 30; j++)
                        {
                            List<Rule> rules = new List<Rule>();

                            // .. generate i rules
                            for(int k = 0; k < i; k++)
                            {
                                // Name of rule starts with r followed by random number in range [0, 9999]
                                string name = "r" + String.Format("{0}", random.Next(0, 10000));
                                // Rule priority is in range [0, 500]
                                int pty = random.Next(1, 501);
                                rules.Add(new Rule(name, pty));
                            }

                            // Write the list of rules to curFile
                            writer.WriteLine(String.Join(", ", rules.ToArray()));
                        };
                    }
                });
        }
    }

然而,尽管如此,输出文件 (filenames.txt) 中的某些行仍然与其他行混在一起。我想知道是否可以在不锁定 StreamWriter 的情况下解决这个问题。

示例输出:

  1. C:\Users\Frank\Documents\visual工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\test1.txt
  2. C:\Users\Frank\Documents\visual工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\test50001.txt
  3. C:\Users\Frank\Documents\visual工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\tesal工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\test37501.txt
  4. C:\Users\Frank\Documents\visual工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\test87501.txt
  5. C:\Users\Frank\Documents\visual工作室2013\Projects\TimedAssignment3\TimedAssignment3\Datasets\test12501.txt

像这样使用返回的 TextWriter

var syncWriter = TextWriter.Synchronized(names);

MSDN(https://msdn.microsoft.com/en-us/library/system.io.textwriter.synchronized(v=vs.110).aspx) 说:

All write operations to the returned wrapper will be thread safe. You call this method to ensure that only one thread at a time can execute the methods on the TextWriter instance that is returned.

Synchronized() 不会创建实例 'synchronized' 但 returns 新的同步实例。