Чтобы ответить на ваш вопрос:
Строковое загрязнение в C # (и .NET в целом) является «безопасным», но выполнение этого в тесном цикле, как вы описываете, может вызвать сильное давление памяти и нагрузку на сборщик мусора.
Я бы рискнул предположить, что ошибки, о которых вы говорите, были связаны с неким исчерпанием ресурсов, но было бы полезно, если бы вы могли предоставить более подробную информацию - например, получили ли вы исключение? Приложение завершилось ненормально?
Справочная информация:
Строки .NET являются неизменяемыми, поэтому, когда вы делаете конкатенацию следующим образом:
var stringList = new List<string> {"aaa", "bbb", "ccc", "ddd", //... };
string result = String.Empty;
foreach (var s in stringList)
{
result = result + s;
}
Это примерно эквивалентно следующему:
string result = "";
result = "aaa"
string temp1 = result + "bbb";
result = temp1;
string temp2 = temp1 + "ccc";
result = temp2;
string temp3 = temp2 + "ddd";
result = temp3;
// ...
result = tempN + x;
Цель этого примера состоит в том, чтобы подчеркнуть, что каждый раз, когда цикл повторяется, выделяется новая временная строка.
Поскольку строки являются неизменяемыми, среда выполнения не имеет альтернативных вариантов, кроме как выделять новую строку каждый раз, когда вы добавляете другую строку в конец своего результата.
Хотя строка result
постоянно обновляется, чтобы указывать на самый последний и наибольший промежуточный результат, вы создаете много этих неназванных временных строк, которые почти сразу становятся пригодными для сбора мусора.
В конце этой конкатенации в памяти будут храниться следующие строки (для простоты предполагается, что сборщик мусора еще не запущен).
string a = "aaa";
string b = "bbb";
string c = "ccc";
// ...
string temp1 = "aaabbb";
string temp2 = "aaabbbccc";
string temp3 = "aaabbbcccddd";
string temp4 = "aaabbbcccdddeee";
string temp5 = "aaabbbcccdddeeefff";
string temp6 = "aaabbbcccdddeeefffggg";
// ...
Хотя все эти неявные временные переменные пригодны для сбора мусора почти сразу, они все равно должны быть распределены. При выполнении конкатенации в тесном цикле это будет сильно напрягать сборщик мусора и, если ничего больше, заставит ваш код работать очень медленно. Я видел влияние производительности на это из первых рук, и оно становится действительно драматичным, когда ваша объединенная строка становится больше.
Рекомендуемый подход - всегда использовать StringBuilder
, если вы выполняете несколько конкатенаций строк. StringBuilder
использует изменяемый буфер для уменьшения количества выделений, необходимых для построения твоя строка.