Ich habe das erwähnte Stück Code jetzt schon mehrmals gesehen, was bringt es, eine Max(a+1, a-1)
? Zuerst dachte ich, es könnte sein, um einen Unterlauf zu verhindern, aber es macht nicht wirklich Sinn, den Unterlauf in diesem Fall nicht zu verhindern.
Antworten
Zu viele Anzeigen?Ein bisschen googeln gibt mir einen Verdacht, dass dies von einigen (möglicherweise fehlerhaft) C# zu VB.NET Konverter-Software entstehen könnte. Das würde erklären, das häufige Auftreten der es.
Hinzugefügt: Yessss, ich gefunden ! Versuchen Sie, den folgenden C#-Code einzugeben und in VB.NET zu konvertieren:
int i;
i++;
Wie Sie erwähnt haben, ist es möglich, dass sie versuchen zu erkennen, wann Offset
auf Null umschlägt (oder negativ wird) und auf dem Höchstwert für den jeweiligen Typ fixiert bleibt Offset
ist. Oder sie versuchen, mit einer Situation umzugehen, in der Offset
in mehreren Threads "gleichzeitig" erhöht wird (oder so ähnlich).
In jedem Fall handelt es sich um fehlerhaften Code.
Wenn sie versuchen, einen Umbruch auf Null oder ins Negative zu erkennen bzw. zu verhindern, verursacht eine zu große Schrittweite ohnehin das Problem. Wenn sie versuchen, sich mit Offset
gleichzeitig' erhöht werden, bin ich mir nicht sicher, welches Problem sie wirklich zu lösen versuchen oder wie sie es zu lösen versuchen.
Hier sind die Probleme:
Allerdings klingt es immer noch seltsam zu mir - weil, wenn Offset flüchtig ist, der letztere Ausdruck möglicherweise nicht den neuesten Wert sowieso erhalten.
Aber es ist noch schlimmer als das - selbst wenn Offset
flüchtig ist, gibt es nichts zu serialisieren, was den neuen Wert von Offset
mit einem anderen Thread, der ihn möglicherweise erhöht, so dass der Moment nach der Max()
Ausdruck liest den Wert von Offset
eine beliebige Anzahl von anderen Threads kann hinzukommen und sie (beliebig oft) erhöhen. Im besten Fall ist der Ausdruck also nutzlos, aber die Verwendung dieser Technik kann schädlich sein, weil Sie am Ende einen Wert von Offset
das nicht zu Ihnen "gehört".
Betrachten Sie die Situation, in der Sie Offset
um einen Array-Index oder etwas anderes zu verfolgen (was angesichts des Namens genau nach dem klingt, was vor sich gehen könnte). Wenn Sie atomar inkrementieren Offset
wird das Array-Element mit diesem Index für Sie verfügbar. Wenn Sie die Max()
Ausdruck wie in der Frage können Sie plötzlich auf einem Array-Element herumtrampeln, das eigentlich zu einem anderen Thread gehört.
Ich kann mir keinen legitimen Grund vorstellen, um die
Max(Threading.Interlocked.Increment(Offset), Offset - 1)
Wie ich schon sagte, ist es bestenfalls harmlos (und nutzlos), aber es könnte zu sehr schwer zu diagnostizierende Probleme - verwenden Sie es nicht .
Dank des Kommentars von Simon Svensson, der auf eine Google-Suche nach der Verwendung in der Frage hinwies, sieht es so aus, als ob dieser Code normalerweise (immer?) von der Ausgabe eines C#-zu-VB.NET-Konverters stammt. Er verwendet diesen Ausdruck sogar zur Inkrementierung lokaler Variablen (Threading ist also kein Problem). In den Fällen, in denen Offset
eine lokale Variable ist, fällt dieser Ausdruck in die nutzlose, aber meist harmlose Sorte (es gibt einen "Fehler", wenn das Inkrement umbricht). Es ist eigentlich mehr oder weniger eine sehr ineffiziente Offset++
Ausdrucks (tatsächlich scheint es die Art und Weise zu sein, wie der Konverter den C#-Ausdruck umwandelt Offset++
zu VB.NET - siehe http://www.telerik.com/community/forums/open-source-projects/code-converter/added-value.aspx#307755 ). Eigentlich ist diese Umwandlung fehlerhaft für Offset++
zurück, weil es den inkrementierten Wert zurückgibt, obwohl es den Wert vor der Inkrementierung zurückgeben sollte.
Das wirklich Schlimme daran ist, dass andere Leute sich diesen Code ansehen und denken könnten: "So muss ich das also verwenden Interlocked.Increment()
".
Nun, das ist nicht dasselbe wie Max(a, a-1)
- denn es gibt die Aufforderung Interlocked.Increment
. Angenommen, ein anderer Thread ändert den Wert von Offset zwischen dem Aufruf von Interlocked.Increment
und die Bewertung von Offset-1
.
Dennoch kommt mir das seltsam vor - denn wenn nicht Offset
flüchtig ist, erhält der letztgenannte Ausdruck möglicherweise ohnehin nicht den neuesten Wert.
Nach all dem kann der Code nicht ziemlich sein
Math.Max(Interlocked.Increment(Offset), Offset-1)
weil der Parameter für Interlocked.Increment
es un ref
Parameter. Der nächstliegende legale Code wäre der folgende:
Math.Max(Interlocked.Increment(ref Offset), Offset-1)
(Das wäre immer noch seltsam, da es eine Variable in Pascal-Grundform bedeutet...)
Wenn Sie vielleicht den genauen Code zeigen könnten im Zusammenhang könnten wir den Punkt ausarbeiten. Ich kann nicht behaupten, dass ich selbst jemals einen solchen Code gesehen habe.
Interlocked.Increment(a)
inkrementiert den Wert von a
atomar. In einer Single-Thread-Anwendung ist es äquivalent zu a++
ist aber etwas langsamer. In einer Multithreading-Anwendung stellt es sicher, dass beide Threads den Wert erhöhen, ohne sich gegenseitig zu behindern. Siehe die MSDN-Referenzseite für weitere Einzelheiten
Warum es in diesem Zusammenhang verwendet wird, kann ich nicht sagen, ohne mehr Code zu sehen.