Accesos seguros para subprocesos a controles de formularios de Windows desde F #

Estoy intentando usar el siguiente código F # para acceder a un control 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()))

Esto es de la excelente plantilla F # para Windows Phone de Daniel Mohl.

He creado una clase para leer básicamente el acelerómetro y activar un evento cuando se sacude el teléfono. El evento se genera como se esperaba, pero por alguna razón se genera en un segundo subproceso, lo que lleva al CLR a lanzar una excepción de "acceso de subproceso cruzado no válido" cuando el controlador de eventos intenta ejecutar este código. La excepción se lanza al source.FindName(s) llamada. Puedo ver un segundo hilo de ejecución, lo que me sorprende porque no generé específicamente un hilo secundario. Quiero decir que no llamé explícitamente a async ni hice nada más en lo que pueda pensar que haría que se iniciara un subproceso de ejecución secundario.

Entonces parece que hay algunos enfoques que podría tomar:

  1. Podría intentar averiguar por qué estoy generando un subproceso secundario cuando no lo he solicitado específicamente y modificar el código para evitar que se genere un subproceso secundario de ejecución.
  2. Podría intentar modificar el (?) función para tener en cuenta varios subprocesos de ejecución, pero realmente me gustaría entender por qué estoy comenzando un segundo subproceso

Creo que probablemente el segundo enfoque sea el mejor, pero realmente me gustaría entender qué estoy haciendo que está causando que se genere un hilo secundario. Me doy cuenta de lo difícil que es responder sin un código específico, pero no me importa investigar esto si alguien me puede indicar la dirección correcta. Creo que esto tiene algo que ver con la plataforma Windows 7 Phone porque el código es, por lo que puedo decir, más o menos la forma idiomática de vincular un control Xaml con el código F #.

Cualquier pensamiento, comentario o sugerencia será muy apreciado.

Publicación cruzada en HubFS así como

preguntado el 08 de enero de 11 a las 19:01

1 Respuestas

El manejo de eventos en WP7 generalmente se maneja en devoluciones de llamada asíncronas. Acceder al acelerómetro no es una excepción.

Deberá dirigir cualquier código que resulte en una actualización de la interfaz de usuario al despachador.

En c # esto se puede hacer como

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

El enfoque para enviar resultados al Dispatcher utilizado en esta publicación también puede ser útil para usted en f #, ya que es más un estilo funcional que imperativo como resultado del uso de Rx.

Código WP7: uso de la API del acelerómetro - blog de Dragos Manolescu (trabajo)

Respondido el 09 de enero de 11 a las 01:01

Gracias Mick, el enlace parece prometedor y estaba mirando las cosas de BeginInvoke pero no lo entendía del todo. - Onorio Catenacci

Esta publicación que escribí le brinda una vista simple de por qué / cuándo usar el despachador. social.msdn.microsoft.com/Forums/en-US/windowsphone7series/… - Mick N

Gracias de nuevo Mick - the Dispatcher.BeginInvoke era exactamente lo que necesitaba. - Onorio Catenacci

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.