#c# #asp.net #multithreading
#c# #asp.net #многопоточность
Вопрос:
Я поддерживаю некоторые существующие страницы и наткнулся на фрагмент кода из System.Threading
, и я не уверен, что с этим делать.
(в этом суть)
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument xmlDoc = GetFromCMS();
var nodes = xmlDoc.SelectNodes("/xpath/to/nodes");
int i = 0;
while (i < nodes.Count)
{
//do stuff with nodes[i]
//last line in while loop - this is where I'm confused
Math.Max(System.Threading.Interlocked.Increment(ref i), i - 1);
}
}
Имеет ли смысл делать что-то подобное? Нельзя ли вместо этого i
увеличить ala i
? Я не разбираюсь в многопоточности, но, учитывая, что на этой странице нет другого многопоточного кода и ничего действительно «особенного» не происходит (не создаются дополнительные потоки и т.д.), Мне это кажется немного странным.
Спасибо за вашу помощь!
Комментарии:
1. Math.Max тоже бесполезен, все это можно переписать в ‘for (int i = 0; i < узлы. Считайте; i ){…}’
2. @SelflessCoder вы правы, этот рефакторинг тоже пропустил.
3. Похоже на ошибку вырезания и вставки
4. похоже, кто-то не знает, что делает!
5. @mitch на нашем сайте так много подобного мусора от других, менее осторожных разработчиков. Но в этом-то и прикол, верно? Как исправить эти маленькие жемчужины?
Ответ №1:
Ваша интуиция верна — код немного странный, вероятно, его можно было бы неплохо представить в DailyWTF.
Я не уверен в первоначальных мотивах разработчиков, но без какого-либо другого контекста метод кажется потокобезопасным. Вы должны иметь возможность увеличивать i
использование i ;
без какого-либо риска.
Еще лучше, вы можете устранить это, i
переписав как foreach
вместо:
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument xmlDoc = GetFromCMS();
var nodes = xmlDoc.SelectNodes("/xpath/to/nodes");
foreach(var node in nodes)
{
//do stuff with node
}
}
Комментарии:
1. отлично, это то, что я подумал! Спасибо
Ответ №2:
i
является локальной переменной (и не используется совместно ни с какими другими потоками), поэтому простой i
безопасен.
Итак, замените это:
Math.Max(System.Threading.Interlocked.Increment(ref i), i - 1);
с этим
i ;
Или, как указал комментатор, замените простым циклом for
или foreach
!
Ответ №3:
Если вы каким-то образом не делитесь локальной i
переменной с другими потоками (что весьма сомнительно), i
будет работать так же хорошо, без накладных расходов на функцию приращения блокировки.
Единственный способ, которым я мог бы увидеть, что это происходит, — это если вы передаете i
по ссылке внутри тела цикла в другую функцию, которая затем поделилась бы этим. Если он используется только локально, все в порядке.
Комментарии:
1. нет, это объявлено там локально, прямо перед
while
началом цикла