Dealing With GUI Threading Issues

Everybody at one point or another runs into a need to deal with threading. I would say the most common occasion is within event handlers. Often something on the application’s form will be updated to reflect information provided in the event handler. The problem with this is that the event handler will frequently be called by code that is running in its own thread.

Let’s say you are using one of the asynchronous methods of the WebClient class. If you try to display the content received in say, a textbox, the debugger will throw an invalid cross-threading exception. While you can technically ignore this as the error will only appear in the debugger, it is NOT recommended as it can lead to stability problems that can be difficult to track down.

Most guides to threading are fairly advanced and often include overly complicated examples. The code below is going to be short and to the point. So let’s get started.

In the example we will use the DownloadStringCompleted event of the WebClient (triggered by a call to WebClient.DownloadStringAsync).

 

C#

delegate void d_StringCompleted(object sender, 
                                DownloadStringCompletedEventArgs e);

void w_DownloadStringCompleted(object sender,
                               DownloadStringCompletedEventArgs e)
{
  if (InvokeRequired) {
    d_StringCompleted callback = w_DownloadStringCompleted;
    BeginInvoke(callback, new object[] { sender, e });
  }
  else {
    TextBox1.Text = e.Result;
  }
}

VB.NET

Delegate Sub d_StringCompleted(ByVal sender As Object, 
                              ByVal e As DownloadStringCompletedEventArgs)

Private Sub w_DownloadStringCompleted(ByVal sender As Object, 
                              ByVal e As DownloadStringCompletedEventArgs)
    If InvokeRequired Then
        Dim callback As d_StringCompleted = w_DownloadStringCompleted
        BeginInvoke(callback, New Object() {sender, e})
    Else
        TextBox1.Text = e.Result
    End If
End Sub

The first line defines our delegate. The idea is to declare the same parameters in the delegate as in the method that will be updating the control. In this case we are just calling the event handler again.

In the first line of the event, we check if InvokeRequired is True. If the code is executing on the same thread as the form, this will be false. Since our event is asynchronous, InvokeRequired will be true as it is called from another thread.

Next we must declare an instance of our delegate, and assign it to the method we’ll be calling. Since we’re calling the same method again, we assign it to w_DownloadStringCompleted.

We then call BeginInvoke. This is used to execute a function on the main (GUI) thread. The first argument is our delegate. The second argument is an Object array containing, in order, the arguments that the callback function expects. Here we simply enter the same variables that are passed to the event, sender and e.

Finally, the function is executed again on the main thread. This time, InvokeRequired is false, so we are safe to alter the contents of the TextBox.

New Home

If you’re reading this. The DNS switch is complete and Codinghut is no longer hosted on GoDaddy.

All humans must re-register

In it’s time here, this site has become increasingly popular, and risen on the google rankings. As a result, there has been a huge increase in spam, both in comments and registrations. So far, I have used my own judgement to determine and delete spam registrations, and have blocked over 4000 comments via Akismet. For a while now I have been wanting to add some kind of validation or spam blocking to registrations and now I finally have. All new registrations, along with comments, will require CAPTCHA validation. 

The good news (for me), is that going forward, I will be spending a LOT less time cleaning up after the scum of the net. The bad news (for you), is that minutes ago, after implementing the CAPTCHA system, I made an executive decision and deleted every user account except my own. So, with that said, everyone who is not a scum spammer, bot, or otherwise waste of life who really thinks people buy Viagra online from someone calling themself il0v3Th3gi4ntC0ks, please do go ahead and re-register your account!

-The Management

Developing for the iPhone / iPod

First of all, let me start by saying I have not yet personally created any iPhone / iPod applications. Using the Cygwin / toolchain method I was able to compile an app but was never successful in getting it to run. Since I do not own a Mac, and have been close but unsuccessful in virtualizing1 OSX, I am fairly limited at the moment. Nonetheless, I have acquired a good deal of resources on the topic, which I will share with others seeking this information.

Apps Amuck
31 sample applications with screen shots and source code. An excerpt from the site: “Over the years, we have given many presentations on developing Mobile applications. One thing that we have heard time and time again is that people have a hard time writing their first mobile application. We think sometimes people have a hard time taking those first steps. It is easy to think that it will take too much time, and that it will be too hard. But that is simply not the case. But instead of telling people, we are going to show them how easy it really is.

Tutorial: The Objective-C Language

Objective-C Beginner’s Guide

Video tutorials for beginners, intermediate and advanced programmers

Xcode 3 Beep Tutorial Video 

Xcode 3 Beep Video Tutorial Part 2: Outlets

Wikibooks: Programming Mac OS X with Cocoa for beginners

iPhone Development Central 600+ Minutes of video tutorials

The Objective-C 2.0 Programming Language, Introduction to The Objective-C 2.0 Programming Language

winChain A project focused on iPhone / iPod development under Windows. If you are a beginner to programming in general, you will likely struggle with this method. Results are mixed even among experienced developers. If you are unfamiliar with Cygwin, this may not be for you.

iPhone Application Programming A free course offered by Stanford University

Apple Developer Connection Free registration required.

Simple RSS Reader tutorial from TheAppleBlog.com

Cocoa Dev Central Cocoa tutorials

BecomeAnXcoder A free book for starting with Cocoa using Objective-C

iCodeBlog A blog focused on iPhone / iPod development

iPhone development questions at Stack Overflow

Well, that’s all I’ve got for now. Hopefully this collection of resources will be found helpful. With luck I will be able to begin developing some apps myself soon.

Enjoy!

  1. If anyone has succeeded in getting OSX to run in VMWare under windows, I would very much like to know how you accomplished this, as I’m sure other readers would as well

How to tell when a WebBrowser has fully loaded, the final answer

Quite often I see in forums people asking how to tell when a hosted WebBrowser control has finished loading. What follows are any of a half a dozen solutions, but often they are either out dated or just don’t work. After fighting with this one again in a project of mine, I have decided to post a solution that DOES work, in VB.NET or C#, VS2005 and VS2008.

If you’ve ever placed code in the DocumentCompleted event, you’ve undoubtedly noticed that it fires multiple times and off the shelf is of little use to determining when the page has actually completed. I’ve seen suggestions ranging from using timers to very complex event sink something or other, most of which don’t quite work. This is one of those things that I cannot imagine how it has not made the documentation.

The solution itself is pretty simple, and also works when the page contains frames, which is a whole other set of forum listings. The key is in the event arguments. In the DocumentCompleted event, e.Url.AbsolutePath contains the URL of the document that has completed. In the case of a page with frames, or one that fetches other pages, those paths will be in the AbsolutePath variable. When the page has truly finished, this will equal the corresponding value of the WebBrowser control. The whole thing looks like this.

C#

void BrowserDocumentCompleted(object sender,
        WebBrowserDocumentCompletedEventArgs e)
{
  if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
    return; 

  //The page is finished loading 
}

VB.NET

Private Sub BrowserDocumentCompleted(ByVal sender As
            Object,  ByVal e As WebBrowserDocumentCompletedEventArgs)
  If e.Url.AbsolutePath <> TryCast(sender, WebBrowser).Url.AbsolutePath 
   Then
    Return
  End If
  'The page is finished loading 
End Sub 

That’s all it takes. Note that the VB.NET code was created with a code translator and has not been tested.

Cheers.

Debugging more efficiently

This is one of those gems that I read about quite a while ago but never used. Especially when working with multiple threads this technique is almost indispensable. How I ever made it before I don’t know.

If you’ve ever debugged your app (and I hope you have), there are few things more irritating than stepping through it and getting stuck in timer events that you don’t care about.

Another example is if you are building anything with network communication. Throw in a few socket events and while a breakpoint will get you where you want to start, the chances of stepping past the breaking function and not landing into a socket event are slim.

Finally, I’m not sure if it’s just differing IDE settings, but the F-keys for stepping through vs over seem to vary on my dev machines. Hitting the wrong one when you get to a function that loops internally 100,000 times, is just annoying.

The cheap solution is to set breakpoints at the beginning of the functions you care about, and just F5 whenever you hit one of the aforementioned events, or in the case of the last example, you would have to set a breakpoint either after the loop or at the next line in the calling function.

Today I was reminded of a MUCH easier way to debug efficiently. I had intended to post a link to the MSDN page for the attribute that performs this wizardry, but such a thing does not exist. Even in the VS help (which is pretty much just MSDN anyhow) there is no mention of it. There is a similarly named class, but this voodoo attribute apparently does not officially exist. In order to use the attribute, you must add a using clause for System.Diagnostics.

Alright, I’ll tell you, all it takes, is one line above the method/function, property accessor, struct or class that you do not want to step through. That line is

[DebuggerStepThrough]

Yep, that’s it. As far as the Framework is concerned, this is a meaningless attribute and serves a purpose only in Visual Studio. It will also not appear in the Intellisense list. I have not tested it with Sharp Develop. For methods, structs and classes, just add that tag above the first line and you’re good to go. For properties, you would place it immediately before the get or set lines.

One thing to remember, is the debugger will pass over any breakpoints that are in the chunk of code the tag applies to. I personally find it easier to just comment the line when I have a need to debug one of the tagged blocks of code. But there is also an option in the IDE. If you go to Tools > Options > Debugging > General (VS2005), and remove the check from Enable Just My Code (Managed only), then the attribute can stay, and breakpoints within the affected blocks will break as expected.

Making Lookout work with Outlook 2007

This article is service 2 purposes:

  1. To provide a solution to those wanting to use the Outlook add-in Lookout in Outlook 2007.
  2. To introduce the companion to this site, a far overdue task.

For most, if you’re reading this article, you’ve been a long-time user of Lookout, an indexing / search add-in for Outlook that packs phenomenal cosmic powers. So now you upgrade to Outlook 2007 and upon launching it for the first time are presented with the following greeting:

Sorry!! it looks like another Outlook Plugin has installed an unofficial version of the Outlook libraries which breaks Lookout.  Lookout will not be able to load.  For more information, see this link: http://www.lookoutsoft.com/Forums/topic.asp?TOPIC_ID=10

Armed with little hope and the psychic vision of the impending 404, you type in the URL from the error to find that the site no longer exists. Frantic, you try Archive.org, Google cache, anything you can think of, the page has effectively been erased from existence.

As Lookout is a .NET application, I instinctively fired up Reflector to have a look. The good news, the problem is solvable with little effort.

With that said, it’s time for point #2. About the time I redesigned Codinghut, I also launched a second site titled Only The Best. It has had little to no mention here, but it’s time to clue you all in. Only The Best is a freeware (thus far) review site. Anyone who knows me would not deny I am the definition of a download junkie. Seeing as I’m already doing the work, I decided to launch a site to present what I feel are the best of the best of the free (again, thus far).

What does this have to do with the topic of this article? Naturally, Lookout was one of the first applications to make it on the list. In the process of writing up the article for it, I encountered this dreaded error (previously I had used Lookout exclusively at work on Outlook 2003, at home I run 2007). Being that I had just reviewed it, after devising a solution I posted it on that site. I toyed with cross posting the article here as there is coding involved, but with my recently gained insight into search engine rankings, duplicating content across sub-domains is not something I care to do.

Ok, ok, enough with the chatter you want the solution. For an explanation of the problem and how to fix it, along with the pre-patched binaries I provide, visit this page.

If you haven’t been paying attention, the link above goes to Only The Best, even if you are not a Lookout user, please do visit the site as you will find only the best picks!

A call to readers

Hi!

Since the inception of Codinghut, my visitors started out few in numbers and have been steadily rising. Certain articles, such as Analyzing windows crash dump files, have become quite popular, yet reader comments are few and far between. VERY few. As stated in my previous post, I am going to start adding more articles containing shorter code segments when I do not have a complete application or class to offer.

So what do you want to read? I do my best to stay well versed in a number of languages and keep up on emerging technologies and methods, and if there’s something you can’t find an answer to, I will do my best to provide an answer or at the least another resource containing an answer. Got a problem you’re trying to solve? Have a task but don’t know where to start? This is the place to voice it.

Comments are always welcome, but I am asking for as many as are willing to post some feedback to this post. Let me know what you would like to see covered here. It is not yet linked from the main site, but you can also visit the Forums to post a question or suggestion. Yes the forums are empty currently, but if enough of you participate, that won’t be for long.

I will not do your homework for you! It is no chore to recognize an obvious homework assignment. If that would be the case, I will offer general pointers or explanations and may provide links to resources that you might actually learn from.

The main point: Take a moment to post at the least a comment of something you would like to see an article on, whether it be a general topic or a specific problem you are encountering.

-Vaelek
+++ATH0

Add a contact to Windows Mobile in C#

I have not posted much lately for one main reason: I like posting complete applications, or at least complete libraries. As it would have it, I do not have the time, energy, or creativity to post complete projects on a basis regular enough to warrant a site devoted to.

As such, I am going to try to start posting tips and snippets here and there between the major projects. I’ve had a number of new registrations to TCH recently and well, users need content. So…

Today I had a need for an automated way to add a contact to a Windows Mobile based device. One would think this is a fairly simple task. It is, however locating actual documentation as to the process to go about it is not so simple.

Read the rest of this entry »

The new Coding Hut

After a few minor, and one MAJOR1 problem, Codinghut has once again been redesigned. As a result, any sites linking to my articles will now point to the front page. Please check below or on the sidebar if you did not reach the page you intended to. There may be a few more changes coming over the next few days, but I’ve worked out just about everything prior to making the switch.

It just occurred to me there is no contact page yet. I will be adding that shortly. If anyone runs into any problems with the new site, please do let me know either by the contact form or by posting a comment.

-Vaelek
+++ATH0

  1. It turns out, my hosting provider (GoDaddy) places a missing.html in the root folder to handle 404’s. After a lot of frustration, I finally figured out that this file must be present even if a custom 404 page is used. Not having it caused all pages other than the front to toss up a very unfriendly 404