I’m trying to use the following F# code to access a Xaml control.
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()))
This is from Daniel Mohl’s excellent F# for Windows Phone template.
I’ve created a class to basically read the accelerometer and trigger an event when the phone is shaken. The event gets raised as expected but for some reason it’s spawned in a second thread–which leads the CLR to throw an “invalid cross-thread access” exception when the event handler attempts to execute this code. The exception is thrown on the source.FindName(s) call. I can see a second thread of execution–which kind of surprises me because I didn’t specifically spawn a secondary thread. I mean I didn’t explicitly call async or do anything else that I can think of that would cause a secondary thread of execution to start.
So it seems like there are a few approaches I could take:
- I could try to figure out why I’m
spawning a secondary thread when I
haven’t specifically requested it and modify the code to prevent a secondary thread of
execution from being spawned. - I could try to modify the (?)
function to account for multiple
threads of execution but I’d really
like to understand why I’m getting a
second thread started
I think probably the second approach is best but I’d really like to understand what I’m doing that’s causing a secondary thread to spawn. I realize how hard that is to answer without specific code but I don’t mind researching this if someone can point me in the right direction. I believe this has something to do with the Windows 7 Phone platform because the code is, as far as I can tell, pretty much the idiomatic way to bind a Xaml control with F# code.
Any thoughts, comments, suggestions would be greatly appreciated.
Cross-posted to HubFS as well
Event handling in WP7 is generally handled on async callbacks. Accessing the accelerometer is no exception.
You’ll need to direct any code that results in a UI update to the dispatcher.
In c# this can be done like
The approach for sending results to the Dispatcher used in this post may also be helpful for you in f# as it’s more of a functional style than imperative as a result of using Rx.
WP7 Code: Using the Accelerometer API – Dragos Manolescu’s (work) blog