2016-08-25 16 views
1

следующий блок кода в C# ввести ли условия гонки:C# Parallel.ForEach вводит условие гонки, когда используется для замены текста файла?

Parallel.ForEach(guidDictionary, (dictionaryItem) => 
    { 
     var fileName = dictionaryItem.Key; 
     var fileText = File.ReadAllText(fileName, Encoding.ASCII); 
     Parallel.ForEach(guidDictionary, (guidObj) => 
     { 
      fileText = fileText.Replace(guidObj.Value.OldGuid, guidObj.Value.NewGuid); 
     }); 

     File.WriteAllText(fileName, fileText); 
    }); 

?

+0

Должно быть хорошо, если это фактические идентификаторы GUID, которые вы заменяете. –

+0

Не поймите, почему существует внутренний 'ForEach' ... если это не упрощенная выборка, вы должны использовать один вызов для' Regex.Replace' вместо создания нескольких копий всего содержимого файла. –

+0

Каждый экземпляр каждого OldGuid должен быть заменен соответствующим NewGuid в данном файле. – devinbost

ответ

6

Да, есть состояние гонки.

fileText = fileText.Replace(guidObj.Value.OldGuid, guidObj.Value.NewGuid); 

Если две отдельные нити начинают эту операцию, они оба будут стартовать на исходной строке. Каким бы ни был закончен первый, он будет записываться в переменную fileText. Когда второй завершится, он также напишет одну и ту же переменную. Но так как оба потока работают на исходной строке, когда второй завершает, изменения, сделанные первым, будут перезаписаны.

+1

Внешний не имеет проблемы, поскольку переменные являются локальными для лямбда. Каждый поток будет иметь свои собственные переменные для работы. – Erik

+2

Похоже, что все имена файлов уникальны, поскольку он выполняет итерацию по клавишам словаря. Стандартный словарь .Net ограничивает ключи уникальными. – Erik

+0

Все имена файлов уникальны. – devinbost