SemaphoreSlim zum Blockieren der Rennbedingung funktioniert nicht, warum?
Posted: 11 Jan 2025, 10:28
Ich habe ein Race-Condition-Problem in einer C#-Avalonia-App und ich habe keine Ahnung, warum.
Die folgende Klasse verfügt über zwei Methoden: wird aufgerufen, wenn das ViewModel beim App-Start erstellt wird.
wird aufgerufen, bevor die App geschlossen wird, über ein Ereignis zur App-Lebensdauer (etwa appLifetime.Exit += viewModel.SaveUserData;). Das Speichern sollte nicht erfolgen, wenn der Ladevorgang noch nicht abgeschlossen ist.
Es gibt jedoch Benutzerberichte, dass das Speichern erfolgt, während der Ladevorgang noch nicht abgeschlossen ist. Was mache ich hier falsch?
Die folgende Klasse verfügt über zwei Methoden:
Code: Select all
LoadUserData()
Code: Select all
SaveUserData()
Code: Select all
public sealed class MainWindowViewModel : ViewModelBase
{
private static readonly SemaphoreSlim mySemaphore = new(1, 1);
public MainWindowViewModel() => LoadUserData();
private void LoadUserData() =>
Task.Run(async () =>
{
await mySemaphore.WaitAsync();
try
{
var items = await Task.WhenAll(UserDataManager.LoadUserItemsAsync());
Dispatcher.UIThread.Post(() =>
{
foreach (var item in items)
AddItem(item);
});
}
finally
{
mySemaphore.Release();
}
});
public void SaveUserData()
{
// should not save if loading didn't finish yet
if (mySemaphore.CurrentCount == 0)
return;
UserDataManager.SaveUserData(this.items);
}
}