Code: Select all
private readonly ConcurrentDictionary _lazyDictionary = new();
Eine der Methoden ist AddOrUpdate, bei der ich die Überladung verwende, um Func zu übergeben s zum Hinzufügen oder Aktualisieren des Wörterbuchs:
Code: Select all
public TValue AddOrUpdate(TKey key, Func valueCreator, Func valueUpdater)
{
return _lazyDictionary.AddOrUpdate(key,
_ => new(valueCreator),
(_, existingLazyValue)
=> new(() => valueUpdater(existingLazyValue.Value).GetAwaiter().GetResult())).Value;
}
Das bereitet mir natürlich Unbehagen, da es in einem Komplex verwendet wird Anwendung, die ich nicht vorstellen möchte Es besteht die Gefahr von Deadlocks, da ich das Problem nicht ohne weiteres aufspüren kann.
Also würde ich diesen Wert zumindest gerne richtig zurückgeben, indem ich darauf warte, dass das Lambda ihn aufruft, aber das lässt sich nicht kompilieren.
Hier ist ein Beispiel für seine Verwendung.
Code: Select all
var pairedDevice = MasterDevices.AddOrUpdate(id,
valueCreator: () => new(this, id, true, devicePairedEventArgs.DeviceInformation.Name),
valueUpdater: async existing =>
{
// do some asynchronous stuff
await existing.VerifyUnderlyingDevice();
return existing;
});
Hilfe willkommen.
Bearbeiten: Bearbeiten: Auf die Kommentare eingehen und etwas hinzufügen eine Implementierung, die ein Semaphor verwendet, um hoffentlich zu verhindern, dass mehrere Aktualisierungsaufrufe gleichzeitig mit den Daten arbeiten. Ich erinnere mich, warum ich es so gemacht habe, weil die Update-Funktion, die den „Verify“-Prozess aufruft, ein Remote-Aufruf in das Betriebssystem ist und jede einzelne Update-Anfrage darauf hinweist, dass eine Änderung hätte vorgenommen werden können. Daher glaube ich nicht, dass Anfragen zur Aktualisierung desselben Werts einfach zusammengefasst werden können, sondern einfach zurückgehalten werden, bis der letzte abgeschlossen ist.
Code: Select all
public TValue AddOrUpdate(TKey key, Func valueCreator, Func valueUpdater)
{
_semaphore.WaitAsync();
try
{
return _dictionary.AddOrUpdate(key, _ => valueCreator(), (_, existingValue) => valueUpdater(existingValue).GetAwaiter().GetResult());
}
finally
{
Trace.Message($"Master count: {_dictionary.Count}");
_semaphore.Release();
}
}
Und auch wenn dies zu funktionieren scheint, löst es nicht die Bedenken, die ich hatte trotzdem GetAwaiter().GetResult() verwenden. Bitte informieren Sie uns.