BeginInvoke Methods and OneWay Attribute
In a previous post I talked about Windows Forms UI Threading using delegates. Recently I needed to replicate what I had learned, and I happened to do so without reviewing my notes in the former blog post. Apparently I didn’t remember everything I had learned and became confused over thread invocation techniques, introducing a bug into my thread messaging. The UI thread was blocking while the background worker thread was processing.
The cause was related to figuring out which BeginInvoke method to call when kicking off the worker thread, the BeginInvoke of the Form object or the BeginInvoke of the delegate. The answer is the BeginInvoke method of the delegate. All of the examples linked to in the previous post had it right, but I got it mixed up with making Invoke or BeginInvoke calls from the background thread using the Form object’s version of these methods. If you don’t care whether your messaging from the background thread is synchronous or asynchronous, then you can use either methods and you can use the ones from the Form object.
The problem is using these Form object methods in order to kick off your background worker thread. The description of the BeginInvoke method on the Form object states that it “executes the specified delegate asynchronously on the thread that the control’s underlying handle was created on.” I translate this to mean that calling your Form object’s BeginInvoke will process on your UI thread. Apparently the delegate BeginInvoke method has no such wording in its description.
Rereading this MSDN article from the former post and reading the Form object’s BeginInvoke method description which I quoted above set me straight and got rid of my blocking UI problem (again).
During this research session, I came across another informative resource when trying to figure out what was meant by potential resource leaks when using BeginInvoke with out later calling EndInvoke. From reading the article, I gather you can substitute the EndInvoke call with the OneWay attribute on the method being invoked, as long as it has a void return signature and no ref nor out parameters. Please let me know if my interpretation is wrong. I added the attribute to my code in the applicable spots and have seen no side effects of doing so. Here is the article on read mentioning this attribute: