VB2005 Magic – Application Startup and MyEvents

Wed, September 1, 2004, 10:20 AM under Whidbey | VisualStudio
With VS2005, VB gets the My feature. Part of the package is a new startup model and MyEvents.

If you look in a VB project properties, you will find a (unchecked by default) checkbox "Startup with custom Sub Main". Below it there are more "Windows Application Properties", including choosing a Splash screen. There is also a button "View Code" which takes you to the partial MyApplication class - you can also go there by showing all files in the solution explorer and navigating to the MyEvents.vb file under My Project. By using the dropdown you can hook into various events e.g. Startup, UnhandledException etc. So how does this work?

Well the first thing to note is that, if you check the "Startup with custom Sub Main" (and provide your own Sub Main OR use the implicit one of a Form1), then none of the events will be caught, so obviously the two are intertwined. Second, if you use the Class Designer to drag the MyApplication class on a diagram and then display the full hierarchy, you will find that it inherits from WindowsFormsApplicationBase (WFAB), which in turn inherits from ApplicationBase. All of these are in the System.Windows.Forms namespace but are defined in the Microsoft.VisualBasic.dll

To continue the exploration, we build a simple VB WindowsApplication in Release mode and place a Trace.Assert(False, “stack") in its Form.Load event handler. After running the app, we see the stack trace in a msgbox that uncovers the startup call path. Usually we'd expect to see our Sub Main function followed by Application.Run and then a whole bunch of other methods (not of interest right now) ending up in Form1_Load. Instead, we notice that the call stack starts with:
MyApplication.Main -> WFAB.Run -> WFAB.DoApplicationModel -> WFAB.OnRun -> Application.Main etc.

And those methods are where the magic is.
OnRun does the following:
-sets the MainForm to be your main form (via OnCreateMainForm)
-hides the splash screen
-sets up the NetworkAvailabilityChanged event
-calls Application.Run

DoApplicationModel does the following:
-shows the splash screen (via OnInitialize)
-Raises the Startup event (via OnStartup)
-calls OnRun (just described above)
-raises the Shutdown event (via OnShutdown)

So how does all this affect the startup performance of VB apps compared to C#? I don't have that answer, but if you go and look in the methods above, you will find a whole bunch of other objects getting created (relative to thread safety, security etc). Also take into account the call path for the creation of MyApplication, e.g. it is in the WFAB.ctor that the StartupNextInstance event gets hooked.

Finally, a separate note on the UnhandledException event: This is setup in DoApplicationModel by hooking into the Application.ThreadException event. DoApplicationModel can also raise the UnhandledException event as a result of an exception occurring around (effectively) Application.Run. We know that there are 3 actions one must take to catch all unhandled exceptions, instead here we see only two! So it is obvious that the AppDomain.UnhandledException has to be separatelly subscribed to by the developer (for catching thread exceptions other than the GUI). I think this is a gotcha and the VB team should also hook into it so that when we catch the UnhandledException in MyEvents.vb we really are catching all unhandled exceptions.

Next time we'll look at the possibility of using this approach (including catching the events) from C#.

Blog link of the week 35

Sat, August 28, 2004, 05:00 PM under Links
Rico gives us Performance Tidbits.

The big news this week are the changes to the shipping/content plans for Longhorn. Chris Sells has all the links here.

Class Designer - The Missing

Thu, August 26, 2004, 10:30 AM under Whidbey | VisualStudio
UPDATED the status of the suggestions on ladybug

Previously in the overview of the Class Designer I focused on the good aspects.

I did not mention two tracking windows that I am not that excited about but you might be, so I'll briefly summarise them.

Each time a shape is selected/clicked in the diagram, there are two windows that get updated: Properties and Class Details (in my configuration on the bottom right and bottom respectively). Class Details is a breakdown of the elements in the shape for finer editing. However, I'd rather double click on the shape and go straight to code where the excellent code editor/intellisense will help me make my change, then Ctrl+TAB and I am back in the diagram. The Properties window shows info already on the diagram (e.g. method name, access modifier), it shows info that should be on the diagram (e.g. method signature, type, whether it is static) and it shows info that I wouldn't mind going to code to see (e.g. Custom Attributes, remarks, summary). I would probably be more enthusiastic about these windows if I didn't know that the development time taken to offer us these could have been used to plug more essential gaps that are there due to "resource constraints".

Talking of gaps in functionality here is a list of features that would greatly improve the tool. They are over at the MSDN Feedback center as suggestions where the problem and proposed solution for each are described.

1 (POSTPONED) Show Full method signature for methods, events, delegates, overloads
(a must have feature whose ommission makes the whole Class Designer almost useless IMHO)

2 (POSTPONED) Support a dependency association
(read my justification for this... it is one of the least appreciated yet most useful of UML IMO)

3 (POSTPONED) Static members should have visual indication on diagram

4 (POSTPONED) Visual distinction of readonly properties

5 (POSTPONED) Event as association and How to show subscription to an event

6 (FIXED) Delegate signature

7 (POSTPONED) Delegates (and other nested types) shown outside the class

8 (POSTPONED) Visual representation/distinction of Namespaces

9 (POSTPONED) Attach notes to classes and associations at least

10 (FIXED) "View in diagram" should not always create a new diagram

11 (POSTPONED) Navigation aid for large class diagram

12 (FIXED) "View in diagram" framework types from Object Browser

13 (POSTPONED) Option to use .NET framework types instead of language types

Class Designer - The Good

Wed, August 25, 2004, 11:05 AM under Whidbey | VisualStudio
So VS2005 brings with it a great feature: the Class Designer.

For those of you unfamiliar with UML, think of it as a diagrammatic compliment to the Object Browser and Class View.

If you are familiar with UML (and its 8-9 diagram types), think Class Diagram but MSFT are going their own way with a slightly different notation.

Classes (reference types) and interfaces are represented by rounded-corner box shapes, and Structures/enumerations (value types) are represented by square boxes. Abstract classes are shown with a dotted line. Each box has up to four sections: Fields, Properties, Methods and Events. This is a great improvement over UML, where you just have 2 sections for attributes and operations; representing anything else requires stereotypes and/or other custom mechanisms. Each member can individually be hidden. Furthermore, each section is collapsible, as is the class as a whole; from a usability point of view this is done easier than in any other tool I have used!

The other item available from the toolbox is a square yellow note for adding comments in free format. While on the subject of color, it is used as a further aid in distinguishing elements on the diagram: classes/structs are blue, delegates red, interfaces green and enums are violet (unless I have become color-blind :-)

Interface implementation is shown via the lollipop shape, and it's good to see just one of these coming out of a class with a list of all the interface names below it: this reduces clatter. Should you wish to view the member of each interface separately, this is just a context menu away: "Show Interface". Inheritance is represented by the UML closed arrow head. The only other relationship supported is open arrow head association (i.e. when a type references another type) and there is an excellent feature where a field/property can be visualised as an association or vice versa: "Show as Association". Naturally, if one of your classes contains a field of a framework type, then showing as association will show a class of the framework type...this is great for reverse engineering the .NET library classes.

The Class Designer is always in synch with your code. In case that was not clear, any change in the class diagram (e.g. adding a method, changing a field) is reflected in code and any change in the code (e.g. deleting a property, changing a delegate) is reflected on the diagram; there is no code generation/reverse engineering step; they are just "naturally" in synch. In fact, if you look at the file (with extension "cd") you will find an XML document with layout and file information, but nothing that describes the members of the types as they are all read via reflection every time the class diagram is displayed. Navigation between the two is easy: going from a diagram element to its code counterpart is a double-click away and at any point in a code file, one can "View in Diagram" the types declared in the file.

Did I mention that Class Designer not only is available for all languages but also for CF projects as well :-D

Next time we'll look at what is still missing...

Blog link of the week 34

Sun, August 22, 2004, 10:45 AM under Links
When it comes to threading we can think of locking in terms of a "linear acquire-do-release approach" or a "callback-based approach". I will not attempt to summarise any further this cool entry by Ian Griffiths.

If you find VB's language/syntax evolution weird/funny then laugh at this from the 3 Leaf guys.

Want to restrict a windows app to a single running instance? The traditional way is via a mutex and K. Scott Allen explains that very well here. As usual, its the gotchas that add the value...

Global Exception Handling (.NET v2.0, CF 2.0) - PART III

Thu, August 19, 2004, 11:23 AM under dotNET
Read the first two parts here and here.

.NET 2.0 fixes the problem with exceptions being swallowed on background threads (based on the VS2005 Beta 1).

When global exception handling is not present, unhandled exceptions on background threads will result in the app either exiting or JIT debug window appearing (based on the reg entry mentioned previously - on my VS2005 Beta 1 installation, the registry entry has the decimal value of 10 so there are clearly more options added in this area; but sorry, I just don't know more about them).

When global exception handling is present, the same rules as today apply, except we also get to see the JIT debugging window before our catch code runs(!). I guess this is for helping us on our dev machines, since by changing the reg entry to 1 the JIT debugging dialog does not appear (phew :-)

UPDATE: The CF 2.0 story is better with the November CTP compared to the Beta 1 story below.

With the CF 2.0, there is still no support for Application.ThreadException or AppDomain.UnhandledException, but the story gets better with try..catch around the main entry point. Basically the bug has been fixed, so the app will not freeze in the Control.Invoke scenario. To recap, if you try..catch the Appliccation.Run then you have two scenarios with CF 2.0:
1. Exceptions on the GUI thread are caught [just as in CF 1.0]
2. Exceptions in other threads (including the Control.Invoke scenario) are caught, BUT before your catch code runs the built-in dialog still appears!

This is the same behaviour with the full Framework (when we use global exception handling) with one major difference. On the desktop we can change the registry setting to override that behaviour - with the CF there is no way that I know of to suppress the built-in dialog :-( Let's hope this situation changes by release time...

Global Exception Handling (.NET CF v1.0) - PART II

Sun, August 15, 2004, 11:19 AM under MobileAndEmbedded
Following from previous entry. If you are working with the Compact Framework 1.0, you should know that exceptions on background threads do result in the unhandled exception dialog appearing on screen. Also on the CF there are no registry entries to configure.

If you wish to add global exception handling to CF apps, you are out of luck. There is no support for Application.ThreadException or AppDomain.UnhandledException. You might think that using a try..catch around the entry point would work, however that is a bad idea. There are three scenarios when you do that:
1. Exceptions on the main GUI thread
2. Exceptions on background threads
3. Exception occurs in the GUI thread as a result of a Control.Invoke from a background thread (which you must do to update GUI areas)

The first scenario is OK - the exceptions are caught and your catch code will run. Your catch code will not run for the second case; in fact the built-in dialog will appear.

The third case is the worst, and I classify this as a bug: in this scenario your app will freeze/lock (and of course your catch code after Application.Run will not run).

So, no centralised global error handling on the CF.

Next time we'll look at how things change with VS2005 and .NET v2.0

Global Exception Handling (.NET v1.1) - PART I

Sun, August 15, 2004, 08:35 AM under dotNET
We should be trapping possible exceptions in various places with the try..catch mechanism, but all software contains bugs and so will your code; in that scenario you still want to catch the exception (log it, present custom GUI to user, etc). To do this on the full Framework 1.1 we use a try..catch around the entry point (typically Application.Run), hook into System.Windows.Forms.Application.ThreadException (for GUI thread exceptions) and hook into AppDomain.CurrentDomain.UnhandledException for other thread exceptions. We need to perform all 3 actions.

There is a good article on the subject in June's edition of MSDN Magazine on the above, go read it.

To finish the desktop story, check out the registry entry described here. Note that, if there is no global error handler mechanism, any exceptions on background threads are swallowed if not explicitly caught. This means the application does not exit or put up a JIT debugging window, it just continues running in whatever state it is in!

Next time we'll look at how things are different with the Compact Framework.

Blog link of the week 33 (as in week ending today)

Sun, August 15, 2004, 05:15 AM under Links
David Cline continues his series on using cordbg on the CF with part VII (check out parts I, II, III, IV, V and VI).

Also, Brian Grunkemeyer on the BCL blog talks about Managed Debugging Assistants (MDA's) in Whidbey, in the context of finalizers.

Finally this week, Wes discusses differences in memory/speed between the Hashtable implementation of Whidbey and the current one.

My CF application and the platform it targets

Tue, August 10, 2004, 03:29 PM under MobileAndEmbedded
I work for a Building Management Systems (BMS) manufacturing company. Our main products are intelligent building controls. In January we replaced our old network display panel with a new hardware platform running Windows CE 4.2. The product's name is IQView.

Our hardware is based on an XScale PXA255 processor 200 MHz with 32 MB RAM. There is no stylus/keyboard/mouse, so user interaction is via 1/4VGA color touchscreen using a finger :-) Connectivity includes rs232, Ethernet and our own proprietary current loop. The unit is always connected to one of the previous options. It can be panel mounted or fixed to the wall (either way this is not a mobile device). In summary, it also has an SD card slot, LED, buzzer and relay output.

IQView allows for discovery of controllers, navigation of modules within them and adjustment of parameters, graphing, alarm reception etc. The application itself is written by myself using .NET CF. This is effectively (not literally) the only process running on the system and the only GUI that the end user interacts with - there are no OS components (control panel applets, taskbar, menus etc) ever visible. It runs 24x7 (assuming none of my bugs creep up :-).

If you want to know more about our choice of CE over other operating systems, our choice of the CF over eVC or want to see an image of the product, then you may find this article [pdf , html] useful. It appeared in EmbeddedSystemsEurope in April and includes quotes from our technology and business managers - us devs never get air time like that :-[

Other references to IQView on the web are
here (Swedish)
here (Finnish)
here (French)
here (German)
here, here, here (English)