Hier ist der Quellcode für ConcurrentStack.TryPop<T>()
(wie durch ILSpy dekompilierten):
public bool TryPop(out T result)
{
ConcurrentStack<T>.Node head = this.m_head;
if (head == null)
{
result = default(T);
return false;
}
if (Interlocked.CompareExchange<ConcurrentStack<T>.Node>(ref this.m_head, head.m_next, head) == head)
{
result = head.m_value;
return true;
}
return this.TryPopCore(out result);
}
Diese Methode liefert false
wenn der Gegenstand nicht entfernt werden kann/zurückgegeben, oder wenn TryPopCore
kehrt false
. Also hier ist, dass:
private bool TryPopCore(out T result)
{
ConcurrentStack<T>.Node node;
if (this.TryPopCore(1, out node) == 1)
{
result = node.m_value;
return true;
}
result = default(T);
return false;
}
so dass gibt zurück, ob TryPopCore(int, out ConcurrentStack<T>.Node)
erfolgreich ist:
private int TryPopCore(int count, out ConcurrentStack<T>.Node poppedHead)
{
SpinWait spinWait = default(SpinWait);
int num = 1;
Random random = new Random(Environment.TickCount & 2147483647);
ConcurrentStack<T>.Node head;
int num2;
while (true)
{
head = this.m_head;
if (head == null)
{
break;
}
ConcurrentStack<T>.Node node = head;
num2 = 1;
while (num2 < count && node.m_next != null)
{
node = node.m_next;
num2++;
}
if (Interlocked.CompareExchange<ConcurrentStack<T>.Node>(ref this.m_head, node.m_next, head) == head)
{
goto Block_5;
}
for (int i = 0; i < num; i++)
{
spinWait.SpinOnce();
}
num = (spinWait.NextSpinWillYield ? random.Next(1, 8) : (num * 2));
}
if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled())
{
CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spinWait.Count);
}
poppedHead = null;
return 0;
Block_5:
if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled())
{
CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spinWait.Count);
}
poppedHead = head;
return num2;
}
Wie Sie sehen können, ist es falsch zurück, wenn es nicht ein Element entfernen und sie dann zurück. Es gibt eine Menge zu dieser letzten Funktion, und der dekompilierte Code ist nicht der sauberste, aber er scheint der Dokumentation zu entsprechen.
Die Dokumentation besagt, dass "false" zurückgegeben wird, wenn die Sammlung kein Element zum Entfernen und Zurückgeben enthält. – Amy
@amy danke für diese Bestätigung –
Ich bin unklar, was Sie hier fragen möchten. Aber nur für den Fall, dass Sie unsicher sind - Sie haben bereits festgestellt, dass dies Multithread-Zugriff ist. Jede * Argumentation *, die Sie bei irgendwelchen Rückgabewerten durchführen, ist * irrelevant * für den Zustand der Sammlung, wenn Sie das nächste Mal versuchen, darauf zuzugreifen. –