I have a WPF program appending to a textbox asynchronously. If the user selects a new provider via combobox, the appending should be cancelled and called again with the new provider. problem is the updateMoviesTask?.Wait() deadlocks. I guess it is because UpdateMovies() waits for ui thread and ProviderId property waits for the task. How can I solve this?
CancellationTokenSource source;
Task updateMoviesTask;
async Task UpdateMovies()
{
source?.Dispose();
source = new CancellationTokenSource();
CancellationToken cancel = source.Token;
var request = new GetPopularRequest(Country.Germany);
for (int i = 1; i <= TotalPages; i++)
{
request.Page = i;
request.ProviderId = providerId;
var getPopularResponse = await justWatchClient.GetPopularAsync(request);
// do ui stuff here
if (cancel.IsCancellationRequested)
return;
}
}
public GetProviderResponse ProviderId
{
get { return providerId; }
set
{
this.providerId = value;
this.source?.Cancel();
updateMoviesTask?.Wait();
updateMoviesTask = this.UpdateMovies();
this.OnPropertyChanged("");
}
}
If I understand correctly, then you need to - Look at this version of the code (without taking into account the handling of possible exceptions):
private CancellationTokenSource source = new();
private readonly object locker = new();
private void UpdateMovies() => Task.Run(() =>
{
source.Dispose();
source = new CancellationTokenSource();
CancellationToken cancel = source.Token;
lock (locker)
{
var request = new GetPopularRequest(Country.Germany);
for (int i = 1; i <= TotalPages; i++)
{
request.Page = i;
request.ProviderId = providerId;
// Need a synchronous version of the method
// var getPopularResponse = await justWatchClient.GetPopularAsync(request);
var getPopularResponse = justWatchClient.GetPopular(request);
// do ui stuff here
if (cancel.IsCancellationRequested)
return;
}
}
});
public GetProviderResponse ProviderId
{
get { return providerId; }
set
{
this.providerId = value;
UpdateMovies();
this.OnPropertyChanged(string.Empty);
}
}