Хобрук: Ваш путь к мастерству в программировании

UIKit.UIKitThreadAccessException: ошибка согласованности UIKit: вы вызываете метод UIKit, который может быть вызван только из потока пользовательского интерфейса

Я пытаюсь запустить этот код:

GetRepsButton.Command = new Command(async () =>
            {
                var url = @"https://url";

                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                //crashes here
                var test = await client.GetStringAsync(url);
            });

И когда я это сделаю, все приложение выйдет из строя, и в окне вывода появится эта ошибка:

ROR: +[MSWrapperLogger MSWrapperLog:tag:level:]/7 Unhandled Exception:
UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.
  at UIKit.UIApplication.EnsureUIThread () [0x00020] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.16/src/Xamarin.iOS/UIKit/UIApplication.cs:89 
  at UIKit.UIGestureRecognizer.RemoveTarget (Foundation.NSObject target, System.IntPtr action) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.16/src/Xamarin.iOS/UIKit/UIGestureRecognizer.g.cs:342 
  at UIKit.UIGestureRecognizer.OnDispose () [0x00016] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.16/src/Xamarin.iOS/UIKit/UIGestureRecognizer.cs:41 
  at UIKit.UIGestureRecognizer.Dispose (System.Boolean disposing) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.16/src/Xamarin.iOS/UIKit/UIGestureRecognizer.g.cs:959 
  at
 Foundation.NSObject.Finalize () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.16/src/Xamarin.iOS/Foundation/NSObject2.cs:143 
Resolved pending breakpoint at 'SelectRep.xaml.cs:110,1' to void NameSpace.<ClientPicker_SelectedIndexChanged1>d__3.MoveNext () [0x0000c].

Хотя я не думаю, что мне следовало бы это делать, поскольку я ничего не делаю с пользовательским интерфейсом, я пробовал InvokeOnMainThread, который не работает. Я также пробовал перейти на .Result вместо await, и я пробовал GetAsync и читал содержимое, используя WebClient вместо HttpClient. Все вызывают одну и ту же ошибку.

Любые идеи? Я использую формы Xamarin с 4 до 7.


  • можете ли вы предоставить больше контекста по этой строке кода? Похоже, трассировка стека исходит от распознавателя жестов, верно? 29.03.2019
  • @Jason Я вообще не делал в проекте распознавателей жестов. Я думаю, что это внутренний код xamarin.ios. Если я закомментирую эту строку .getstringaync, приложение будет работать нормально. 29.03.2019
  • Я бы предположил, что этот ожидаемый вызов находится где-то в методе возврата void и, таким образом, вызывает связанный сбой в некотором коде пользовательского интерфейса (ваш код или код предварительного просмотра Forms4 не сможет определить без дополнительного контекста, как / где вы используете / вызываете это httpclient асинхронный метод. 29.03.2019
  • @SushiHangover, код находился внутри Clicked Event (private async void ClientPicker_SelectedIndexChanged1(object sender, EventArgs e)) на Button, единственный вариант - void, насколько я понимаю? Однако я изменил его, чтобы установить команду с помощью асинхронной команды, и по-прежнему возникла та же проблема. Я обновил свой вопрос, чтобы показать полный блок кода. Я неправильно понимаю, как выполнять асинхронные вызовы при нажатии кнопки? 29.03.2019
  • @SushiHangover, это также происходит, если я использую WebClient.DownloadString(), который вообще не является асинхронным. 29.03.2019
  • @Kyle Нет, вы правы (обработчики событий на основе void неизбежны ...). Вы удаляете где-нибудь этот обработчик событий? Что-то вызывает странный сбой. Хотите знать, когда вы говорите, что ClientPicker_SelectedIndexChanged1 находится на кнопке, это кнопка или средство выбора? ?? 29.03.2019
  • Я нигде не удаляю событие, оно находится на кнопке. Извините, я знаю, что в названии есть Picker, что сбивает с толку. Код изначально запускался всякий раз, когда средство выбора изменялось и использовало значения средства выбора, но я пытался сузить код, поэтому я поместил его на кнопку и жестко закодированные значения, чтобы получить минимальный код. 29.03.2019
  • После 8 часов попыток заставить это работать я переключился на Visual Studio 2017 вместо предварительной версии 2019 года, и она отлично работает. Я предполагаю, что это ошибка версии xamrarin.ios или mono, которая поставляется с превью 2019 года, я думаю ... 30.03.2019

Ответы:


1

Используйте Device.BeginInvokeOnMainThread

Device.BeginInvokeOnMainThread(() =>
{
  //your code
});

https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.device.begininvokeonmainthread?view=xamarin-forms

21.09.2020
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..