В нашей игре GnollHack мы используем .NET MAUI 9.0 Preview 5, .NET SDK 9.0 Preview 5 и SkiaSharp 3.0 Preview 3.1. SKGLView из SkiaSharp использует SwapChainPanel для рендеринга графики с ускорением графического процессора в Windows/WinUI3. Некоторое время все работает нормально, но затем игра вылетает со следующим исключением (находится в окне «Вывод → Отладка»):
Исключение, созданное по адресу 0x00007FFB236EF39C (KernelBase.dll) в GnollHackM.exe: ошибка источника WinRT — 0x80004005: «В этом приложении XAML обнаружен повторный вход. Используйте отладчик, чтобы найти реентерабельный код и, при необходимости, переместите этот код в асинхронный обработчик событий. Нажмите ОК, чтобы выйти из приложения.'.
Microsoft.ui.xaml.dll!00007FFA8F1137D8: CallContext:[\ImageDecodeActivity] 8000FFFF — E_UNEXPECTED
Необработанное исключение по адресу 0x00007FFA8F4A52F5 (Microsoft.ui.xaml.dll) в GnollHackM.exe: 0xC000027B: произошло внутреннее исключение приложения (параметры: 0x0000022A8ED086C0, 0x0000000000000003).
Это происходит в режиме отладки, но это происходит и в режиме выпуска.
Отладчик всегда завершает работу при выполнении оператора lock.
GnollHackM.dll!GnollHackM.GamePage.PaintMainGamePage(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e) Line 7517 C#
GnollHackM.dll!GnollHackM.GamePage.canvasView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e) Line 3860 C#
GnollHackM.dll!GnollHackM.SwitchableCanvasView.internalGLView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintGLSurfaceEventArgs e) Line 213 C#
[External Code]
GnollHackM.dll!GnollHackM.SwitchableCanvasView.InvalidateSurface() Line 75 C#
GnollHackM.dll!GnollHackM.GamePage.UpdateMainCanvas() Line 1325 C#
GnollHackM.dll!GnollHackM.SwitchableCanvasView.OnPropertyChanged(string propertyName) Line 352 C#
[External Code]
GnollHackM.dll!GnollHackM.SwitchableCanvasView.GeneralAnimationCounter.set(long value) Line 331 C#
GnollHackM.dll!GnollHackM.GamePage.StartMainCanvasAnimation.AnonymousMethod__415_0(double v) Line 1611 C#
[External Code]
Спасибо. Я сообщил нашему программисту. Надеюсь, ему удастся провести рефакторинг кода в соответствии с лучшими практиками.





Нам пришлось добавить DispatcherQueue.TryEnqueue в очередь нашего метода InvalidateSurface. Нам пришлось использовать окно DispatcherQueue, а не то, которое прикреплено к нитке (это было медленно).
Похоже, проблема с потоками. Почему у вас есть блокировки повсюду в том, что кажется методом пользовательского интерфейса (поэтому к нему должен обращаться только один поток)? Вы вызываете этот метод с несколькими потоками? И даже с блокировками этот тип кода неверен
if (_currentGame != null) { lock (_currentGame.WindowsLock) { for (int i = 0; _currentGame.Windows..., поскольку ссылку _currentGame следует скопировать локально (во время блокировки она может стать нулевой)