Migration der Verwendung von .GetAwaiter().GetResult() in einer Lambda-Anweisung zu asyncC#

Ein Treffpunkt für C#-Programmierer
Guest
 Migration der Verwendung von .GetAwaiter().GetResult() in einer Lambda-Anweisung zu async

Post by Guest »

Angesichts dieses ConcurrentDictionary:

Code: Select all

private readonly ConcurrentDictionary _lazyDictionary = new();
Ich habe eine Wrapping-Klasse, die benutzerdefinierten Zugriff auf das Wörterbuch bietet...
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;
}
Wie wir sehen können, hat die valueUpdater-Funktion eine Rückgabesignatur von Task>, aber um sie auf das zugrunde liegende Wörterbuch selbst anzuwenden, muss sie gerecht sein der zurückgegebene TValue, sodass Sie die Verwendung von .GetAwaiter().GetResult() sehen können.
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;
});
Wie auch immer, Copilot und ich können das nicht herausfinden.
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();
}
}
Obwohl mir klar ist, dass das Einbeziehen von Lazy immer noch helfen würde, Schritt für Schritt ...
Und auch wenn dies zu funktionieren scheint, löst es nicht die Bedenken, die ich hatte trotzdem GetAwaiter().GetResult() verwenden. Bitte informieren Sie uns.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post