Using reflection to determine whether an object needs its members to be invoked on the GUI thread

StackOverflow https://stackoverflow.com/questions/10125465

  •  31-05-2021
  •  | 
  •  

Question

Referencing this FsEye issue, how can I use reflection to determine whether an object needs its members (or indeed a specific member if possible) to be invoked on the GUI thread?

The scenario is this: a user creates an instance of a WebBrowser object within FSI (which runs its own WinForms event loop), then they attempt to expand the node in FsEye. But that results in an unhandled exception dialog box warning that

System.Threading.ThreadStateException: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.

(specifically this appears to occur when loading the AccessibilityObject property only).

I know this is because FsEye loads child nodes lazily, asynchronously, and in parallel using F# async computation expression with Async.Parallel and thus is invoking members of this OLE object from non-original, non-STA (i.e. not the original FSI GUI thread) thread pool threads. I also know how to fix this by switching to the GUI thread context within my async expressions, but I would only like to do that when absolutely necessary.

Was it helpful?

Solution

There is no single member you can look at to determine if an object needs to be invoked from a STA / main thread of the application. It's just something that is inherent in the contract of an individual type

That being said there are certain clues you can look for. These would indicate an object is a UI bound component but by no means is this a definitive list

  • Derives from System.Windows.Forms.Control
  • Derives from UIElement
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top