Yes, it is odd for me to post an entry on this blog covering thread safe ways to talk to windows user controls in C#, but I was surprised at how much trolling I had to do on Google/MSN in order to piece together a complete answer, so I figured I would share my complete situation and final(for now) solution.
In this particular situation, I have a windows form with a tab control, with one of the tabs hosting a text box control that displays messages. This control is not initially visible to the user, yet it is instantiated during the main form construction.
The first issue to resolve was to get the logging class and other components to make thread safe calls to this control. Microsoft has a great tutorial posted about making thread safe calls to Windows forms controls, so I won’t repeat that code or explanation here.
Where I had to step beyond the MSDN article was in handling the thread safe calls to a form whose handle property may or may not be created. I am not a Windows GDI expert, I barely know what it means, but one thing I did find out during this process is that I could not guarantee when the handle for the control was created, even though its constructor was called by the containing form constructor during the application start.
To handle this, there were two steps I needed to take:
- Ensure that the control’s handle was instantiated and available on the same thread as the main UI. To do this, I simply added this line to my code following the construction of the user control on the main form: IntPtr userControlHandle = textUserControl.Handle; This ensures that the control’s handle is not created on the background thread when you cann or access properties or methods on the control
- I next added these lines of code to my user control:
delegate void SolveThreadingDelegate();
public void UserControl()
this.Invoke(new SolveThreadingDelegate (UserControl));
The logging pounds this control pretty well and so far I have gotten around some of the previous locking issues I experienced – it now handles well thousands of messages an hour flying at it (not all displayed on the screen at a time, but still a constant stream of information) and I have yet to have a cross thread access violation pop up.
Hopefully this helps anyone else stuck in a similar situation; if anyone has improvements, suggestions or questions, please feel free to post.