diff --git a/osu.Game/Online/Leaderboards/LeaderboardManager.cs b/osu.Game/Online/Leaderboards/LeaderboardManager.cs
index 5750c83c97..632771afc1 100644
--- a/osu.Game/Online/Leaderboards/LeaderboardManager.cs
+++ b/osu.Game/Online/Leaderboards/LeaderboardManager.cs
@@ -7,6 +7,7 @@ using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
@@ -24,7 +25,11 @@ namespace osu.Game.Online.Leaderboards
{
public partial class LeaderboardManager : Component
{
+ ///
+ /// The latest leaderboard scores fetched by the criteria in .
+ ///
public IBindable Scores => scores;
+
private readonly Bindable scores = new Bindable();
public LeaderboardCriteria? CurrentCriteria { get; private set; }
@@ -47,6 +52,9 @@ namespace osu.Game.Online.Leaderboards
///
public void FetchWithCriteria(LeaderboardCriteria newCriteria, bool forceRefresh = false)
{
+ if (!ThreadSafety.IsUpdateThread)
+ throw new InvalidOperationException(@$"{nameof(FetchWithCriteria)} must be called from the update thread.");
+
if (!forceRefresh && CurrentCriteria?.Equals(newCriteria) == true && scores.Value?.FailState == null)
return;
diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs
index aeb21b09cb..eaf0369e32 100644
--- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs
+++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs
@@ -20,6 +20,8 @@ namespace osu.Game.Screens.Ranking
{
private readonly IBindable globalScores = new Bindable();
+ private TaskCompletionSource? requestTaskSource;
+
[Resolved]
private IAPIProvider api { get; set; } = null!;
@@ -37,6 +39,14 @@ namespace osu.Game.Screens.Ranking
globalScores.BindTo(leaderboardManager.Scores);
}
+ protected override void Dispose(bool isDisposing)
+ {
+ base.Dispose(isDisposing);
+
+ if (requestTaskSource?.Task.IsCompleted == false)
+ requestTaskSource.SetCanceled();
+ }
+
protected override async Task FetchScores()
{
Debug.Assert(Score != null);
@@ -48,13 +58,18 @@ namespace osu.Game.Screens.Ranking
leaderboardManager.CurrentCriteria?.Scope ?? BeatmapLeaderboardScope.Global,
leaderboardManager.CurrentCriteria?.ExactMods
);
- var requestTaskSource = new TaskCompletionSource();
+
+ Debug.Assert(requestTaskSource == null || requestTaskSource.Task.IsCompleted);
+
+ requestTaskSource = new TaskCompletionSource();
+
globalScores.BindValueChanged(_ =>
{
if (globalScores.Value != null && leaderboardManager.CurrentCriteria?.Equals(criteria) == true)
requestTaskSource.TrySetResult(globalScores.Value);
});
- leaderboardManager.FetchWithCriteria(criteria, forceRefresh: true);
+
+ Schedule(() => leaderboardManager.FetchWithCriteria(criteria, forceRefresh: true));
var result = await requestTaskSource.Task.ConfigureAwait(false);