fix ui deadlock problem

This commit is contained in:
beo3000 2026-01-09 13:29:37 +01:00
parent 310cc0e2ec
commit 3b6c7a2234
3 changed files with 33 additions and 8 deletions

View File

@ -92,6 +92,11 @@ Break complex work into 3-5 stages. Document in `IMPLEMENTATION_PLAN.md` see [do
- Handle errors at appropriate level - Handle errors at appropriate level
- Never silently swallow exceptions - Never silently swallow exceptions
Be aware of critical patterns, that can lead to deadlocks or other problem when using async methods. E.G.:
- Search(pattern: "@\(_.*\.Result\)", glob: "*.razor", output_mode: "content")
- Search(pattern: "\)\.Result", glob: "*.razor", output_mode: "content")
- Search(pattern: "\.Wait\(\)", glob: "*.razor", output_mode: "content")
## Decision Framework ## Decision Framework
When multiple valid approaches exist, choose based on: When multiple valid approaches exist, choose based on:

View File

@ -46,7 +46,7 @@
@if (_model.LastThrow != null) @if (_model.LastThrow != null)
{ {
<MudAlert Severity="@GetLastThrowSeverity()" Class="mb-4" Dense="true"> <MudAlert Severity="@GetLastThrowSeverity()" Class="mb-4" Dense="true">
@(_ = GetLastThrowMessage().Result) @_lastThrowMessage
</MudAlert> </MudAlert>
} }
@ -172,18 +172,21 @@
private DeathBoxGameModel? _model; private DeathBoxGameModel? _model;
private List<PlayerStatsRow> _playerStats = []; private List<PlayerStatsRow> _playerStats = [];
private int _activePlayerCount = 0; private int _activePlayerCount = 0;
private string _lastThrowMessage = "";
protected override void OnInitialized() protected override async Task OnInitializedAsync()
{ {
base.OnInitialized(); await base.OnInitializedAsync();
GameState.StateChanged += OnGameStateChanged; GameState.StateChanged += OnGameStateChanged;
UpdateStats(); UpdateStats();
_lastThrowMessage = await GetLastThrowMessage();
} }
private void OnGameStateChanged(object? sender, EventArgs e) private async void OnGameStateChanged(object? sender, EventArgs e)
{ {
UpdateStats(); UpdateStats();
InvokeAsync(StateHasChanged); _lastThrowMessage = await GetLastThrowMessage();
await InvokeAsync(StateHasChanged);
} }
private void UpdateStats() private void UpdateStats()

View File

@ -63,13 +63,14 @@
</HeaderContent> </HeaderContent>
<RowTemplate> <RowTemplate>
<MudTd> <MudTd>
@if (context.ContentType.StartsWith("image/")) @if (context.ContentType.StartsWith("image/"))
{ {
<img src="@context.Url" style="max-width: 60px; max-height: 40px;" /> <img src="@context.Url" style="max-width: 60px; max-height: 40px;"/>
} }
else else
{ {
<MudIcon Icon="@Icons.Material.Filled.Movie" Size="Size.Large" /> <MudIcon Icon="@Icons.Material.Filled.Movie" Size="Size.Large"/>
} }
</MudTd> </MudTd>
<MudTd DataLabel="Name"> <MudTd DataLabel="Name">
@ -80,7 +81,7 @@
@foreach (var evt in GetAssignedEvents(context.AssignedEvents)) @foreach (var evt in GetAssignedEvents(context.AssignedEvents))
{ {
<MudChip T="string" Size="Size.Small" Color="GetEventColor(evt)" Variant="Variant.Outlined" Class="mr-1"> <MudChip T="string" Size="Size.Small" Color="GetEventColor(evt)" Variant="Variant.Outlined" Class="mr-1">
@(_ = Term.GetThrowEventName(evt).Result) @GetEventName(evt)
</MudChip> </MudChip>
} }
</MudTd> </MudTd>
@ -245,6 +246,7 @@
private bool _isLoading = true; private bool _isLoading = true;
private string? _error; private string? _error;
private int _pendingCount => _gifs.Count(g => g.IsPendingApproval); private int _pendingCount => _gifs.Count(g => g.IsPendingApproval);
private Dictionary<ThrowEventType, string> _eventNames = new();
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@ -259,6 +261,7 @@
var clubId = ClubContext.ClubId; var clubId = ClubContext.ClubId;
_gifs = (await GifService.GetByClubAsync(clubId, includePending: true)).ToList(); _gifs = (await GifService.GetByClubAsync(clubId, includePending: true)).ToList();
_tokens = (await GifService.GetSubmissionTokensByClubAsync(clubId)).ToList(); _tokens = (await GifService.GetSubmissionTokensByClubAsync(clubId)).ToList();
await LoadEventNames();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -267,6 +270,17 @@
finally finally
{ {
_isLoading = false; _isLoading = false;
StateHasChanged();
}
}
private async Task LoadEventNames()
{
var eventTypes = new[] { ThrowEventType.Strike, ThrowEventType.Circle, ThrowEventType.Bell,
ThrowEventType.Gutter, ThrowEventType.NoWood, ThrowEventType.Cleared };
foreach (var evt in eventTypes)
{
_eventNames[evt] = await Term.GetThrowEventName(evt);
} }
} }
@ -516,6 +530,9 @@
return result; return result;
} }
private string GetEventName(ThrowEventType type) =>
_eventNames.TryGetValue(type, out var name) ? name : type.ToString();
private static Color GetEventColor(ThrowEventType type) => type switch private static Color GetEventColor(ThrowEventType type) => type switch
{ {
ThrowEventType.Strike => Color.Success, ThrowEventType.Strike => Color.Success,