Проблемы с Центром многопоточности и обмена сообщениями в Xamarin.forms - PullRequest
0 голосов
/ 14 ноября 2018

Я разрабатываю другой пример, в котором Messaging Center отправляет сообщения о состоянии, не связанные с кодом устройства, на модели моего вида.

На данный момент я использовал:

  • Аварийное сообщение;
  • Метка на мой взгляд;
  • Метод путем внедрения зависимостей из собственного кода (ранее создавался и взаимодействовал).

Чтобы заметить события, прежде чем попробовать в Просмотр моделей ... и т.д.

Для этого я использовал экземпляр статического представления в своем конструкторе приложения общего доступа (App.xaml), где в конструкторе представления я добавляю статус.

Приложение (общедоступное)

public partial class App : Application
    {
        public static ConnectViewModel CVM { get; set; }// Connection View Model
        #region MasterDetailPage
        public static MasterDetailPage MDP;
        public static NavigationPage NAV = null;
        public static MainView _mainpage;
        #endregion

        public App ()
        {
            InitializeComponent();
            InitializeApplication();
            NAV = new NavigationPage(new StarterView()) { BarBackgroundColor = Color.FromHex("701424"), BarTextColor = Color.White }; ;
            MDP = new MasterDetailPage();
            MDP.BackgroundColor = Xamarin.Forms.Color.FromHex("701424");
            _mainpage = new MainView();
            MDP.Master = _mainpage;
            MDP.Detail = NAV;
            MainPage = MDP;
            MainPage.Title = "H2X";

        }
 private void InitializeApplication()
        {

            if (CVM == null)
            {
                CVM = new ConnectViewModel();
            }
        }

(Просмотреть общий доступ)

public MainView ()
        {
            InitializeComponent ();

            string a="Test";
            #region MessegeCenter

            MessagingCenter.Subscribe<string,string>("APP", "Message_Received", async (sender,arg) => 
            {
                string b = a;
                a = $"{arg}";

                try
                { 
               * await DisplayAlert(App.BM_Status, "Ok", "OK");*
                }catch(Exception e)
                {
                string a = e.Message;
                }
               * generic_label_of_my_view = generic_label_of_my_view + "+";//It's not async one*
                *string test = App.CVM.All_conn.Msg_Reciever();//Injection - It's not async one*

            });
            #endregion

        }

В код конкретной платформы (Устройство - UWP):

  • Я создаю таймер, который через некоторое время отправляет сообщения в конструкторе главной страницы.
  • HID-устройство, которое замечает меня, когда приходит какое-то сообщение от USB.

Диспетчер Таймер

void dispatcherTimer_Tick(object sender, object e)
         {
             DateTimeOffset time = DateTimeOffset.Now;
             TimeSpan span = time - lastTime;
             lastTime = time;
             //Time since last tick should be very very close to Interval
             TimerLog.Text += timesTicked + "\t time since last tick: " + span.ToString() + "\n";
             timesTicked++;
             if (timesTicked > timesToTick)
             {                   
                 MessagingCenter.Send<string,string>("APP","Message_Received","MR");
             }
         }

Событие HIDInit и HID InputReport

        public async void HID_Init()
        {


            var selector = HidDevice.GetDeviceSelector(a_Id, b_Id, c_ID, d_ID);
            var devices = await DeviceInformation.FindAllAsync(selector);

            if (devices.Any())
            {
                // At this point the device is available to communicate with
                // So we can send/receive HID reports from it generically


                console_text = "HID devices found: " + devices.Count;

                device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id, FileAccessMode.ReadWrite);

                if (device != null)
                {
                    // At this point the device is available to communicate with
                    // create my input caller/event
                    device.InputReportReceived += inputReportReceived;//invoke caller

                    deviceWatcher = DeviceInformation.CreateWatcher(selector);
                    deviceWatcher.Removed += deviceRemovedEventHandler;//checa se nada foi removido
                    deviceWatcher.Start();
                }
                else
                {
                    // There were no HID devices that met the selector criteria
                    throw new Exception("MUTT HID device not found");
                }

            }
            else
            {
                // There were no HID devices that met the selector criteria
                console_text = "HID device not found";
            }
        }

        private void inputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
        {
            var bbytes = new byte[10];
            wait_streaming = true;
            DataReader dataReader = DataReader.FromBuffer(args.Report.Data);
            dataReader.ReadBytes(bbytes);

            console_text += System.Text.Encoding.ASCII.GetString(bbytes, 2, bbytes[1]);

            is_read = false;

            wait_streaming = false;

            MessagingCenter.Send<string,string>("App","Message_Received","MR");

        }

Когда я запускаю любой случай с Dispatchertimer "работает".

Когда я запускаю событие Hidinputreport с параметром alertmessage, создается сообщение system.exception в строке alertmessege.

Это «исключение System.Exception»

if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
            UnhandledException += (sender, e) =>
            {
                if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
            };
endif

Когда я запускаю событие Hidinputreport с меткой, происходит аварийное завершение интерфейса с другим потоком в моем вызове из messegingCenter в нативном коде.

System.Exception: 'The application call a marshalled interface for another thread.

 (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))'

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

Могу ли я позвонить в отправителя в Центр подписки Messeging?

Как я могу исправить другие проблемы с потоками? Ручной сброс событий? EventWaitHandle? (Наследование: Object -> MarshalByRefObject -> WaitHandle-> EventWaitHandle) ... таким инвазивным способом: /

Извините, если я задам какой-нибудь глупый вопрос или покажу здесь глупый код ... но я не знаю, как его организовать ХОРОШО

Заранее спасибо

Гильерме

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...