Потокобезопасный доступ к элементам управления формы Windows из F # - PullRequest
1 голос
/ 08 января 2011

Я пытаюсь использовать следующий код F # для доступа к элементу управления Xaml.

let (?) (source:obj) (s:string) =
    match source with 
    | :? ResourceDictionary as r ->  r.[s] :?> 'T
    | :? Control as source -> 
        match source.FindName(s) with 
        | null -> invalidOp (sprintf "dynamic lookup of Xaml component %s failed" s)
        | :? 'T as x -> x
        | _ -> invalidOp (sprintf "dynamic lookup of Xaml component %s failed because the component found was of type %A instead of type %A"  s (s.GetType()) typeof<'T>)
    | _ -> invalidOp (sprintf "dynamic lookup of Xaml component %s failed because the source object was of type %A. It must be a control or a resource dictionary" s (source.GetType()))

Это из превосходного шаблона F # для Windows Phone Дэниела Мохла.

Я создал класс, который в основном считывает акселерометр и запускает событие при встряхивании телефона. Событие вызывается, как и ожидалось, но по какой-то причине оно порождается во втором потоке, что приводит к тому, что CLR генерирует исключение «недопустимый межпоточный доступ», когда обработчик события пытается выполнить этот код. Исключение выдается при вызове source.FindName(s). Я вижу второй поток выполнения - который удивляет меня, потому что я специально не создавал дополнительный поток. Я имею в виду, что я явно не вызывал async и не делал ничего другого, о чем я мог подумать, что могло бы вызвать запуск вторичного потока выполнения.

Похоже, есть несколько подходов:

  1. Я мог бы попытаться выяснить, почему я порождая вторичный поток, когда я специально не просили об этом и измените код, чтобы предотвратить вторичный поток казнь от порождения.
  2. Я мог бы попытаться изменить (?) функция для учета нескольких нити исполнения, но я бы на самом деле хотел бы понять, почему я получаю второй поток начался

Я думаю, что второй подход лучше, но мне бы очень хотелось понять, что я делаю, что вызывает появление вторичного потока. Я понимаю, как трудно ответить без конкретного кода, но я не против исследовать это, если кто-то может указать мне правильное направление. Я полагаю, что это как-то связано с платформой Windows 7 Phone, потому что, насколько я могу судить, код - в значительной степени идиоматический способ связать элемент управления Xaml с кодом F #.

Любые мысли, комментарии, предложения будут с благодарностью.

Перешли к HubFS , а также

1 Ответ

3 голосов
/ 09 января 2011

Обработка событий в WP7 обычно обрабатывается при асинхронных обратных вызовах. Доступ к акселерометру не является исключением.

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

В c # это можно сделать как

Dispatcher.BeginInvoke( () => { /* your UI code */ } );

Подход для отправки результатов в Dispatcher, используемый в этом посте, также может быть полезен для вас в f #, так как это скорее функциональный стиль, чем обязательный в результате использования Rx.

Код WP7: Использование API акселерометра - блог Драгоша Манолеску (работа)

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