Ich denke, Sie haben möglicherweise missverstanden, was lock
für Sie tut. Es nicht verhindern anderen Code aus dem Objekt manipulieren, dass Sie eine Sperre ausgeführt haben. Es verhindert, dass ein Thread ein Long in einem Objekt erhält, während ein anderer Thread das Lock hält.
Wenn Sie verhindern möchten, dass ein Thread die Sammlung manipuliert, während ein anderer Thread darüber iteriert, müssen Sie sowohl den Iterationscode als auch den Manipulationscode in lock
Blöcke setzen und dasselbe Objekt sperren.
Einfaches Beispiel:
class LockDemo
{
private IList<string> _items;
private object _lock = new object();
public LockDemo()
{
_items = new List<string>(new[] { "one", "two", "three" });
}
public void RemoveItem(string item)
{
lock (_lock)
{
_items.Remove(item);
}
}
public void DoSomethingThatIteratesOverTheList()
{
lock (_lock)
{
foreach (var item in _items)
{
// do something with item
}
}
}
}
Beachten Sie, wie alle Zugriff auf die Liste (mit Ausnahme des Konstruktor in diesem Fall) in lock
Blöcken gewickelt ist, die alle Sperren auf demselben Objekt ist. Beachten Sie auch, dass dieses Objekt nicht die Liste selbst ist, sondern ein Objekt, das nur zum Sperren verwendet wird. Dies zeigt, dass lock
das Objekt nicht als solches sperrt, sondern einen Mechanismus bereitstellt, um zu steuern, welche Teile des Codes von verschiedenen Threads parallel ausgeführt werden können oder nicht.
Wo ist der Code, der allThreads ändert? Sperrt es auch die Sammlung? –