如何使用StreamWriter避免竞争条件

时间:2015-04-05 04:25:51

标签: c# .net race-condition

根据:https://msdn.microsoft.com/en-us/library/system.io.streamwriter%28v=vs.110%29.aspx,"默认情况下,StreamWriter不是线程安全的。请参阅TextWriter.Synchronized以获取线程安全的包装。"所以我编写了一个方法并使用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 studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ test1.txt
  2. C:\ Users \ Frank \ Documents \ visual studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ test50001.txt
  3. C:\ Users \ Frank \ Documents \ visual studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ tesal studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ test37501.txt
  4. C:\ Users \ Frank \ Documents \ visual studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ test87501.txt
  5. C:\ Users \ Frank \ Documents \ visual studio 2013 \ Projects \ TimedAssignment3 \ TimedAssignment3 \ Datasets \ test12501.txt

1 个答案:

答案 0 :(得分:2)

像这样使用返回的TextWriter

var syncWriter = TextWriter.Synchronized(names);

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

  

对返回的包装器的所有写操作都是线程安全的。您   调用此方法以确保一次只能执行一个线程   返回的TextWriter实例上的方法。

Synchronized()不会使实例“同步”,而是返回新的同步实例。