Sunday, January 30, 2005
- "You should log unhandled exceptions, not just swallow them!" I have met many that refuse to adopt my advice (usually the type that love
- Some obvious, some not so obvious; overall a great post that brings together in one place the wisdom of when to go async and related advice
- Some humour on Unit testing :-D
(if you are a sensitive TDD advocate, keep your knickers on please, it is only a joke!)
On Error Resume Next). If I can't convince you of the opposite, maybe this blog entry will.
- Some obvious, some not so obvious; overall a great post that brings together in one place the wisdom of when to go async and related advice
- Some humour on Unit testing :-D
(if you are a sensitive TDD advocate, keep your knickers on please, it is only a joke!)
Labels: Links
Friday, January 28, 2005
For those that write Compact Framework applications for custom CE devices, the VS emulators are not as useful as they are for PPC development.
We always advise people to get an SDK from the device manufacturer – or even better an actual device to test against. I have been lucky to be playing with a real device from day 1, never having to use the emulator for real development. If you are trying to generate an SDK from Platform Builder, you may find that it is not easy to get it right first time, and more often than not you end up with a black-screen emulator that VS.NET 2003 cannot connect to. The fun bit is where the emulator works OK in eVC, and then when you try to use it in VS, not only it doesn't work but it actually hoses the emulator in such a way that it stops working in eVC, but I digress.
So I thought it useful to include here the *exact* steps that work for us when building (and exporting) an SDK for use in both VS and eVC. Enjoy :-)
1. Make a new platform based on Emulator BSP
2. Configure the image as you require (make sure the image includes .NET Compact Framework, toolhelp.dll and Smart Device Authentication Utility)
3. Make sure that KITL support is disabled in the image (i.e. when you select Platform -> Settings -> Build Options, the only thing that should be checked is "Enable EBOOT Space in Memory")
4. Build the Emulator image
5. Configure the SDK
On the emulation tab - this is up to you e.g. memory size = 64MB and screen size = 320x240, 8 bit
On the transports tab - Make sure Microsoft KITL Transport is *not* checked, set ActiveSync as the default
On the Development Languages Tab - Select everything (so the same SDK will work in eVC++ and VS.NET)
On the Startup Servers tab - Make sure they're all selected and that ActiveSync is the default.
6. Build the SDK
We always advise people to get an SDK from the device manufacturer – or even better an actual device to test against. I have been lucky to be playing with a real device from day 1, never having to use the emulator for real development. If you are trying to generate an SDK from Platform Builder, you may find that it is not easy to get it right first time, and more often than not you end up with a black-screen emulator that VS.NET 2003 cannot connect to. The fun bit is where the emulator works OK in eVC, and then when you try to use it in VS, not only it doesn't work but it actually hoses the emulator in such a way that it stops working in eVC, but I digress.
So I thought it useful to include here the *exact* steps that work for us when building (and exporting) an SDK for use in both VS and eVC. Enjoy :-)
1. Make a new platform based on Emulator BSP
2. Configure the image as you require (make sure the image includes .NET Compact Framework, toolhelp.dll and Smart Device Authentication Utility)
3. Make sure that KITL support is disabled in the image (i.e. when you select Platform -> Settings -> Build Options, the only thing that should be checked is "Enable EBOOT Space in Memory")
4. Build the Emulator image
5. Configure the SDK
On the emulation tab - this is up to you e.g. memory size = 64MB and screen size = 320x240, 8 bit
On the transports tab - Make sure Microsoft KITL Transport is *not* checked, set ActiveSync as the default
On the Development Languages Tab - Select everything (so the same SDK will work in eVC++ and VS.NET)
On the Startup Servers tab - Make sure they're all selected and that ActiveSync is the default.
6. Build the SDK
Labels: Mobile and Embedded
Thursday, January 27, 2005
In a Sentence (or five)
When NETCF controls are created they have a default Font. You would expect the default Font to be picked from the platform (operating system) default Font. However, that is not the case and instead they start of with Tahoma. This cannot be defended as a design choice so it must be a bug! Vote for it to be fixed (the bug is present in CF 1.0 and CF 2.0).
Repro Steps
1. Create a new form
2. Add a button to it (or any other control including custom ones)
3. In the button event handler put the following code:
MessageBox.Show(this.Font.Name,Button1.Font.Name); //C#
MessageBox.Show(Me.Font.Name,Button1.Font.Name) ' VB
4. You see Tahoma, Tahoma (assuming your system default is Tahoma)
5. Change the system's default Font to Arial or Courier New (or some other Font on your unit)
HKLM\System\GDI\SysFnt\Nm
HKLM\System\GWE\Menu\BarFnt\Nm
HKLM\System\GWE\Menu\popFnt\Nm
6. Reset the unit and run the test again
7. You see Arial, Tahoma (they should both be Arial - or whatever the system default is)
Why Fix the Bug
1. 99.99% of controls never have their Font changed by the developer; in fact the only times we change font is for size or style, not name. Hence we expect the Font to be the system default.
2. If we run an app like that on a unit where the default font has changed, it will not pick it up.
3. eVC defaults to system Font so there is no precedence of hardcoding default fonts
4. As the repro steps show, there is inconsistency within the implementation itself. The title bar caption/text the default font whereas the other controls use the hardcoded Tahoma
5. Further inconsistency is that the menu fonts are picked up properly. Even the built-in error handler dialog picks up the correct Font.
6. Changing the Font of every control in Smart Device projects is more cumbersome than the desktop since changing the Font of a container (e.g. Form, Panel) does not propagate to the children controls (no Ambient properties on CF)
How I came across it
Due to other reasons, we have to change the default font of our platform to Arial. Half the screens look odd and I now have to go and explicitly change the Font for all controls. Yes I know "poor me" but that is not the point. Next time we decide to change the default Font I will have to change the hardcoded values since the NETCF controls are not smart enough to pick the default.
When NETCF controls are created they have a default Font. You would expect the default Font to be picked from the platform (operating system) default Font. However, that is not the case and instead they start of with Tahoma. This cannot be defended as a design choice so it must be a bug! Vote for it to be fixed (the bug is present in CF 1.0 and CF 2.0).
Repro Steps
1. Create a new form
2. Add a button to it (or any other control including custom ones)
3. In the button event handler put the following code:
MessageBox.Show(this.Font.Name,Button1.Font.Name); //C#
MessageBox.Show(Me.Font.Name,Button1.Font.Name) ' VB
4. You see Tahoma, Tahoma (assuming your system default is Tahoma)
5. Change the system's default Font to Arial or Courier New (or some other Font on your unit)
HKLM\System\GDI\SysFnt\Nm
HKLM\System\GWE\Menu\BarFnt\Nm
HKLM\System\GWE\Menu\popFnt\Nm
6. Reset the unit and run the test again
7. You see Arial, Tahoma (they should both be Arial - or whatever the system default is)
Why Fix the Bug
1. 99.99% of controls never have their Font changed by the developer; in fact the only times we change font is for size or style, not name. Hence we expect the Font to be the system default.
2. If we run an app like that on a unit where the default font has changed, it will not pick it up.
3. eVC defaults to system Font so there is no precedence of hardcoding default fonts
4. As the repro steps show, there is inconsistency within the implementation itself. The title bar caption/text the default font whereas the other controls use the hardcoded Tahoma
5. Further inconsistency is that the menu fonts are picked up properly. Even the built-in error handler dialog picks up the correct Font.
6. Changing the Font of every control in Smart Device projects is more cumbersome than the desktop since changing the Font of a container (e.g. Form, Panel) does not propagate to the children controls (no Ambient properties on CF)
How I came across it
Due to other reasons, we have to change the default font of our platform to Arial. Half the screens look odd and I now have to go and explicitly change the Font for all controls. Yes I know "poor me" but that is not the point. Next time we decide to change the default Font I will have to change the hardcoded values since the NETCF controls are not smart enough to pick the default.
Labels: Mobile and Embedded
Wednesday, January 26, 2005
Most people associate Compact Framework target devices with Pocket PCs only. This is very convenient for the developer in many ways, e.g. a screen resolution of 240x320 and the presence of a stylus are presumed in most cases.
Imagine you are targeting a device with a very small display (e.g. 105x32mm, 240x64pixels). Naturally, you need to maximise the amount of elements you can fit on a screen, to make it useful. If you take the imaginary scenario further and say that the display is *not* touchscreen (instead hardware buttons provide the only way to drive the UI), then it becomes even more obvious that the GUI controls should be as small as possible (just large enough to read and as small as you can get away with).
Imaginary scenarios interest me, so I thought I'd see how the CF (and by extension WinCE) caters for such an eventuality. The focus is on the Height of controls (Width is not only pretty much adjustable, but also not the dominant limiting factor).
Naturally the following controls are irrelevant: Panel, PictureBox and Timer.
The following controls can be resized (and where applicable their Font is changeable to accommodate the size reduction):
Button, Label, TextBox, ListBox, ProgressBar, TabControl, TrackBar, Datagrid, TreeView, ListView, HScrollBar and VScrollBar
The Toolbar does not have a Size property, but its height is controlled by the size of the images associated with it (on custom WinCE devices, not PPC!). So by adding 8x8 icons to the ImageList associated with the toolbar (or by just changing the ImageSize property), the toolbar will be high enough to fit those images - nice. Like the Toolbar, the TreeView and ListView also play nice with the image size (if there is an ImageList associated with them, otherwise like I said in the previous paragraph, the Size/Font properties also work).
Once the size and Font of controls such as ListView, ListBox and TreeView is decreased, it sticks out like a sore thumb that their scrollbars are too thick. Not a big problem, though, as this can be controlled by the following registry settings:
Menus (MainMenu, ContextMenu and MenuItem) are resized according to their Font. However, they do not expose a Font property, so you are stuck with whatever the default Font is for the platform. You can change that through the registry:
The following controls are problematic:
-DomainUpDown and NumericUpDown can have their height changed but, before you get too excited, their Font is *not* changeable and in fact attempting to assign a Font results in a NotSupportedException at runtime! Net result: these controls have, effectively, a fixed minimum height (The CF 2.0 story is the same, except now the Font property is not exposed at all).
-ComboBox and StatusBar have the reverse problem: You can change their Font but not their Height - it compiles but no runtime change is observed (The CF 2.0 story is the same, except now the Height property is not exposed at all).
-CheckBox and RadioButton shrink, but the square box and circle respectively are of fixed size!
-We saw that menus can be shrunk based on Font size, but the Menu bar *height* is not configurable.
Showing off some of the above is this screen capture
VOTE for the WinCE/NETCF teams to improve in this area.
We already saw registry settings for scrollbars and menu font, here is one more that helps (reset is required before any effect takes place for all these):
For more registry entries see here. I have played with all of them on our platform and found that they are more geared for large displays rather than smaller ones. In other words, the defaults are already targetting small displays, so if you want to go smaller there isn't much there :-(
Imagine you are targeting a device with a very small display (e.g. 105x32mm, 240x64pixels). Naturally, you need to maximise the amount of elements you can fit on a screen, to make it useful. If you take the imaginary scenario further and say that the display is *not* touchscreen (instead hardware buttons provide the only way to drive the UI), then it becomes even more obvious that the GUI controls should be as small as possible (just large enough to read and as small as you can get away with).
Imaginary scenarios interest me, so I thought I'd see how the CF (and by extension WinCE) caters for such an eventuality. The focus is on the Height of controls (Width is not only pretty much adjustable, but also not the dominant limiting factor).
Naturally the following controls are irrelevant: Panel, PictureBox and Timer.
The following controls can be resized (and where applicable their Font is changeable to accommodate the size reduction):
Button, Label, TextBox, ListBox, ProgressBar, TabControl, TrackBar, Datagrid, TreeView, ListView, HScrollBar and VScrollBar
The Toolbar does not have a Size property, but its height is controlled by the size of the images associated with it (on custom WinCE devices, not PPC!). So by adding 8x8 icons to the ImageList associated with the toolbar (or by just changing the ImageSize property), the toolbar will be high enough to fit those images - nice. Like the Toolbar, the TreeView and ListView also play nice with the image size (if there is an ImageList associated with them, otherwise like I said in the previous paragraph, the Size/Font properties also work).
Once the size and Font of controls such as ListView, ListBox and TreeView is decreased, it sticks out like a sore thumb that their scrollbars are too thick. Not a big problem, though, as this can be controlled by the following registry settings:
HKLM\System\GWE , DWORD values "cxHScr", "cyHScr", "cxVScr", "cyVScr"
Menus (MainMenu, ContextMenu and MenuItem) are resized according to their Font. However, they do not expose a Font property, so you are stuck with whatever the default Font is for the platform. You can change that through the registry:
HKLM\Menu\BarFnt , DWORD "Ht" for height , DWORD "Wt" for boldness: 700 or 400
HKLM\Menu\PopFnt same as above, but this applies to menu items rather than the menu bar
The following controls are problematic:
-DomainUpDown and NumericUpDown can have their height changed but, before you get too excited, their Font is *not* changeable and in fact attempting to assign a Font results in a NotSupportedException at runtime! Net result: these controls have, effectively, a fixed minimum height (The CF 2.0 story is the same, except now the Font property is not exposed at all).
-ComboBox and StatusBar have the reverse problem: You can change their Font but not their Height - it compiles but no runtime change is observed (The CF 2.0 story is the same, except now the Height property is not exposed at all).
-CheckBox and RadioButton shrink, but the square box and circle respectively are of fixed size!
-We saw that menus can be shrunk based on Font size, but the Menu bar *height* is not configurable.
Showing off some of the above is this screen capture
VOTE for the WinCE/NETCF teams to improve in this area.
We already saw registry settings for scrollbars and menu font, here is one more that helps (reset is required before any effect takes place for all these):
HKLM\System\GWE , DWORD "cyCap" changes the height of a windows caption/title bar. Note that, if the Font is not changed accordingly, the text will not be rendered.
For more registry entries see here. I have played with all of them on our platform and found that they are more geared for large displays rather than smaller ones. In other words, the defaults are already targetting small displays, so if you want to go smaller there isn't much there :-(
Labels: Mobile and Embedded
Tuesday, January 25, 2005
Continuing from part A (if you haven't read it, we'll wait for you...go on then :-)
5. Take over the device
Popular desire amongst devs is to take over the device. Their app is so important that nothing else should be accessible. This is not as bad as it may sound, as in some cases the application really is the raison d'etre of the device. Every solution described seems to create more issues, so there doesn't seem to be a clean one-rule-fits-all. If you have this requirement, here are some links for you to pursue [1, 2, 3, 4, 5, 6] (in other words search for "full screen" and "kiosk")
6. File System
The storage system on PPCs is similar to the desktop, with only a couple of differences. There is no C:\ drive; everything starts at the root, so an example path is this: "\Program Files\Some Folder\MyApp.exe". More importantly, there is no concept of current directory, the implication of which is that you must always use absolute paths (like the example above). To get the directory of your NETCF app, see this. Note that the OpenFileDialog will only let you browse the "My documents" directory, so if you need to go to other places you have to create your own.
7. Memory Constraint
An obvious difference with PPC devices is the limited memory that is available. When the device runs into low memory situations, it will start closing open windows (this is not minimising, it is real closing). If you get in such a scenario, some people advise to try hooking into the WM_HIBERNATE/WM_CLOSE windows msg; I advise you to revisit your architecture and not consume so much memory in the first place. Measure and set the expected memory your app requires to run smoothly, and if it doesn't get that on a device, it simply means the environment does not meet your criteria. You should, of course, be cleaning up resources in the Form.Closing events in any case. For more on memory problems see Memory Problems FAQ
8. Deployment
Deployment is quite different on devices than to the PC and all links you need on this topic are already provided here
9. Question: "How do I take advantage of my existing desktop .NET code?"
Answer: Share the code
If you are using the NETCF for targetting a device other than PPC (like me), you cannot make any of the above statements without knowing the specifics of the device (all custom CE-based devices are different). In this MSDN article, you can see some of the differences between PPC projects and WinCE projects in VS.NET 2003. I may do an entry on the topic too, at some point in the future.
5. Take over the device
Popular desire amongst devs is to take over the device. Their app is so important that nothing else should be accessible. This is not as bad as it may sound, as in some cases the application really is the raison d'etre of the device. Every solution described seems to create more issues, so there doesn't seem to be a clean one-rule-fits-all. If you have this requirement, here are some links for you to pursue [1, 2, 3, 4, 5, 6] (in other words search for "full screen" and "kiosk")
6. File System
The storage system on PPCs is similar to the desktop, with only a couple of differences. There is no C:\ drive; everything starts at the root, so an example path is this: "\Program Files\Some Folder\MyApp.exe". More importantly, there is no concept of current directory, the implication of which is that you must always use absolute paths (like the example above). To get the directory of your NETCF app, see this. Note that the OpenFileDialog will only let you browse the "My documents" directory, so if you need to go to other places you have to create your own.
7. Memory Constraint
An obvious difference with PPC devices is the limited memory that is available. When the device runs into low memory situations, it will start closing open windows (this is not minimising, it is real closing). If you get in such a scenario, some people advise to try hooking into the WM_HIBERNATE/WM_CLOSE windows msg; I advise you to revisit your architecture and not consume so much memory in the first place. Measure and set the expected memory your app requires to run smoothly, and if it doesn't get that on a device, it simply means the environment does not meet your criteria. You should, of course, be cleaning up resources in the Form.Closing events in any case. For more on memory problems see Memory Problems FAQ
8. Deployment
Deployment is quite different on devices than to the PC and all links you need on this topic are already provided here
9. Question: "How do I take advantage of my existing desktop .NET code?"
Answer: Share the code
If you are using the NETCF for targetting a device other than PPC (like me), you cannot make any of the above statements without knowing the specifics of the device (all custom CE-based devices are different). In this MSDN article, you can see some of the differences between PPC projects and WinCE projects in VS.NET 2003. I may do an entry on the topic too, at some point in the future.
Labels: Mobile and Embedded
I haven't gone off topic in a while and today this pushed me to do so. The moral of Ian's story (although he doesn't state it like that) is do not change your main email account in Passport if you are using messenger. Reason I found the post interesting is because I was considering doing exactly that and now I am put off for good. Maybe it will be fixed in Messenger 7.0
You are using the BETA of 7.0, right? If you are not here are two reasons to do so (apart from the fact that it has been very stable for me in the past week):
1. Ability to sign in invisible
2. In addition to typing messages you can also handwrite them
You are using the BETA of 7.0, right? If you are not here are two reasons to do so (apart from the fact that it has been very stable for me in the past week):
1. Ability to sign in invisible
2. In addition to typing messages you can also handwrite them
Labels: Random
Monday, January 24, 2005
With the Compact Framework making programming for devices so easy, there is an increasing number of desktop developers making the move to CF development (or at least getting their feet wet). They face the challenges of a .NET Framework that is missing whole areas (e.g. Remoting, COM Interop, ASP.NET) and has every interface trimmed down (e.g. the Thread has only 2 public instance members) - it is not called the *Compact* Framework for nothing. Many of my blog entries focus on exactly that: the differences between the full and compact frameworks and sometimes how to bridge the gap.
However, another difference is the actual operating system or platform. This bites the developer even more if they are not daily users of a Pocket PC (which is the target of 95% of the NETCF developers). The situation described has as a consequence a lot of questions in the CF newsgroup, so I will try to address some of these in this entry and point to it in the future (as an FAQ).
1. Input methods
PPCs do not have a mouse or a keyboard (for the few devices that have, keyboard events are supported by some NETCF controls since Service Pack 2). The lack of a mouse is catered by a touch screen and the use of a stylus (mouse events are not supported in most controls and you may need to create your own control; help for custom controls is here, here and here). Right-click context menus are simulated by tap-and-hold (made possible by the aygshell.dll that is part of the PPC platform). There is a Soft Input Panel (SIP), which is a software keyboard that can pop up on the screen. To interact with it, you must reference
2. Form/Dialog size
Forms and dialogs on the PPC are always full screen (the only exception to that rule is the built-in MessageBox). There are known workarounds, but it seems that they hurt more than they help, so my advice is to stick with full screen dialogs and design for that approach from day 1. Try to design the UI so the user never gets the impression they are interacting with more than one screen; use multiple hidden panels on one form and swap them in/out as appropriate.
3. App/Form closing
The design guidelines for the PPC are clear: Applications do not exit/close, instead they minimise. This aids in the concept of a device that is always on (and the apps are always available, without waiting for them to load each time). For NETCF apps, setting the
4. Moving between applications
Following from points 2 & 3 above, you might wonder how you switch between applications. There are various ways: By closing (minimising really) windows, you can reach the desired one OR you can use the top-right Start menu (Windows icon) OR open the
In my opinion, these are the top 4 gotchas for desktop devs moving to the PPC platform. Look forward to the next 4 or 5 in part B.
However, another difference is the actual operating system or platform. This bites the developer even more if they are not daily users of a Pocket PC (which is the target of 95% of the NETCF developers). The situation described has as a consequence a lot of questions in the CF newsgroup, so I will try to address some of these in this entry and point to it in the future (as an FAQ).
1. Input methods
PPCs do not have a mouse or a keyboard (for the few devices that have, keyboard events are supported by some NETCF controls since Service Pack 2). The lack of a mouse is catered by a touch screen and the use of a stylus (mouse events are not supported in most controls and you may need to create your own control; help for custom controls is here, here and here). Right-click context menus are simulated by tap-and-hold (made possible by the aygshell.dll that is part of the PPC platform). There is a Soft Input Panel (SIP), which is a software keyboard that can pop up on the screen. To interact with it, you must reference
Microsoft.WindowsCE.Forms.dll and drag the InputPanel control onto your form. To show it, you call InputPanel1.Enabled = true, typically in the GotFocus event of a TextBox (and set it to false in the LostFocus). To detect when it is up or down, you can track the InputPanel.EnabledChanged event. Note that hand-in-hand with the InputPanel is the MainMenu control that your form must have - even if it doesn't use it (!)2. Form/Dialog size
Forms and dialogs on the PPC are always full screen (the only exception to that rule is the built-in MessageBox). There are known workarounds, but it seems that they hurt more than they help, so my advice is to stick with full screen dialogs and design for that approach from day 1. Try to design the UI so the user never gets the impression they are interacting with more than one screen; use multiple hidden panels on one form and swap them in/out as appropriate.
3. App/Form closing
The design guidelines for the PPC are clear: Applications do not exit/close, instead they minimise. This aids in the concept of a device that is always on (and the apps are always available, without waiting for them to load each time). For NETCF apps, setting the
Form1.MinimizeBox to true will display the X button in the top right, whereas MinimizeBox=false will instead show a little OK button in the top right. Clicking an X minimizes the form, whereas clicking an OK closes the form and by extension the application if the form is the application's main form. Note that minimising is not identical to the desktop, i.e. all that happens to the window is that it is pushed to the back of the stack of open windows on the PPC. To programmatically know when a smart minimize occurs, you should hook into the Form1.Deactivate event (which is supported even though designer support is missing).4. Moving between applications
Following from points 2 & 3 above, you might wonder how you switch between applications. There are various ways: By closing (minimising really) windows, you can reach the desired one OR you can use the top-right Start menu (Windows icon) OR open the
Start->Settings->System->Memory->Running Programs screen. The "Running Programs List" displays all the open windows (minimised or not) and allows you to switch between them. This presents a problem in a scenario where your app has Form_A opening Form_B and you only expect the user to get back to Form_A after closing Form_B; they can also go to Form_A by using the "Running Programs List"! The workaround is to only show in the list the active form and to do that you must set the caption (Form1.Text) of other forms to String.Empty (""). By the way, if you are having trouble bringing your application to the front programmatically, read that.In my opinion, these are the top 4 gotchas for desktop devs moving to the PPC platform. Look forward to the next 4 or 5 in part B.
Labels: Mobile and Embedded
Sunday, January 23, 2005
By now you know about the yesfollow OR the chance to bid for an hour's consultancy with payment going to the victims... I will also remind you that the next installment of the training we mentioned last week is out - of particular interest the talk about progressive API...
Instead, go give a piece of your mind about default Form instances in VB (why would they listen now when they didn't before is a different matter)
I've already given a piece of my mind on the Class Designer in the past but I am still interested in new Beta 2 features.
Instead, go give a piece of your mind about default Form instances in VB (why would they listen now when they didn't before is a different matter)
I've already given a piece of my mind on the Class Designer in the past but I am still interested in new Beta 2 features.
Labels: Links
Saturday, January 22, 2005
We looked at the implementation of EventWaitHandle for the NETCF 1.0 & 2.0
Here, I offer an implementation of Semaphore (another new Whidbey class inheriting from WaitHandle). If you are looking for it (e.g. in your Object Browser), note that unlike every other System.Threading class, it is in System.dll (and not mscorlib) (!)
Get the C# version from OpenNETCF (like most of my other contributions, in 1.3), and the VB version is available right now: Semaphore.vb
Here, I offer an implementation of Semaphore (another new Whidbey class inheriting from WaitHandle). If you are looking for it (e.g. in your Object Browser), note that unlike every other System.Threading class, it is in System.dll (and not mscorlib) (!)
Get the C# version from OpenNETCF (like most of my other contributions, in 1.3), and the VB version is available right now: Semaphore.vb
Labels: Mobile and Embedded
Wednesday, January 19, 2005
We looked at the absense of a nice class from NETCF (today & tomorrow). Here I will offer an implementation of the .NET 2.0 EventWaitHandle for the NETCF.
The C# version is over at the SDF, and the VB version is right here
Take note of inheritance limitations as described before, and obviously I have omitted parts of the interface that do not apply on WinCE. Finally, if you only wanted the class for CF 1.0 or just for CF 2.0, there are changes you can apply to the implementation - as it stands, it works on both :-)
The C# version is over at the SDF, and the VB version is right here
Take note of inheritance limitations as described before, and obviously I have omitted parts of the interface that do not apply on WinCE. Finally, if you only wanted the class for CF 1.0 or just for CF 2.0, there are changes you can apply to the implementation - as it stands, it works on both :-)
Labels: Mobile and Embedded
Tuesday, January 18, 2005
As part of some restructuring for my app, I had to dig into the abstract System.Threading.WaitHandle class. As you'd expect, this is different on NETCF to the Full Fx, and both have changed with Whidbey (based on November CTP).
NETCF 1.0 vs .NET 1.1
The CF version does not provide the WaitAll or WaitAny methods; it only provides the basic parameterless overload of WaitOne. Comparing the total number of members (fields, properties, methods) regardless of scope, we find the CF version having half the members than the Full Fx (13 vs 26).
.NET 1.1 vs .NET 2.0
The main addition we'll get is the public static SignalAndWait methods (3 overloads). The class grows by 9 members in total. The other change is the replacement of the Handle type. Instead of using an IntPtr, it is now of the newly introduced SafeWaitHandle (of the new Microsoft.Win32.SafeHandles namespace)
NETCF 1.0 vs NETCF 2.0The WaitHandle in CF 2.0 brings no changes compared to CF 1.0 apart from implementing the IDisposable.Dispose method (that the Full Fx classes do in all versions).
Getting to the point
So why am I looking at this class? Well actually, I am not interested in the class itself; it is the derived classes that are interesting, and to understand an object's behaviour you must understand its parents. In .NET 1.1 and NETCF 1.0 the public inheritance relationship is:
In .NET 2.0 this changes with the introduction of a new class (and the one that interests me) EventWaitHandle:
EventWaitHandle is not supported in CF 2.0 and, in fact, the whole inheritance hierarchy remains the same in CF 2.0 as it is today (i.e. Figure A). Ignoring Semaphore for the time being (maybe a subject of a future post), I would have urged you to go vote but the inclusion of EventWaitHandle to NETCF has already been postponed.
The main use of this class would be for creating named events which play a prominent role in Inter-Process Communication on WinCE.
Next time we'll look at wrapping the pinvokes required to offer a class that exposes the same interface as EventWaitHandle (unfortunately, though, it cannot fit in the same inheritance hierarchy as the desktop, i.e. we cannot change the existing Compact Framework XXXXResetEvent classes to inherit from the EventWaitHandle we introduce, rather than the WaitHandle that they do).
NETCF 1.0 vs .NET 1.1
The CF version does not provide the WaitAll or WaitAny methods; it only provides the basic parameterless overload of WaitOne. Comparing the total number of members (fields, properties, methods) regardless of scope, we find the CF version having half the members than the Full Fx (13 vs 26).
.NET 1.1 vs .NET 2.0
The main addition we'll get is the public static SignalAndWait methods (3 overloads). The class grows by 9 members in total. The other change is the replacement of the Handle type. Instead of using an IntPtr, it is now of the newly introduced SafeWaitHandle (of the new Microsoft.Win32.SafeHandles namespace)
NETCF 1.0 vs NETCF 2.0The WaitHandle in CF 2.0 brings no changes compared to CF 1.0 apart from implementing the IDisposable.Dispose method (that the Full Fx classes do in all versions).
Getting to the point
So why am I looking at this class? Well actually, I am not interested in the class itself; it is the derived classes that are interesting, and to understand an object's behaviour you must understand its parents. In .NET 1.1 and NETCF 1.0 the public inheritance relationship is:
Figure A
WaitHandle : MarshalByRefObject
|-> Mutex
|-> AutoResetEvent
|-> ManualResetEvent
In .NET 2.0 this changes with the introduction of a new class (and the one that interests me) EventWaitHandle:
Figure B
WaitHandle : MarshalByRefObject
|-> Mutex
|-> EventWaitHandle
|-> AutoResetEvent
|-> ManualResetEvent
|->Semaphore
EventWaitHandle is not supported in CF 2.0 and, in fact, the whole inheritance hierarchy remains the same in CF 2.0 as it is today (i.e. Figure A). Ignoring Semaphore for the time being (maybe a subject of a future post), I would have urged you to go vote but the inclusion of EventWaitHandle to NETCF has already been postponed.
The main use of this class would be for creating named events which play a prominent role in Inter-Process Communication on WinCE.
Next time we'll look at wrapping the pinvokes required to offer a class that exposes the same interface as EventWaitHandle (unfortunately, though, it cannot fit in the same inheritance hierarchy as the desktop, i.e. we cannot change the existing Compact Framework XXXXResetEvent classes to inherit from the EventWaitHandle we introduce, rather than the WaitHandle that they do).
Labels: Mobile and Embedded
Monday, January 17, 2005
This is the title of a blog post that immediately got my attention. I had to dig further, so here is the process.
Look at the attribute with a decompiler:
If you think drilling deeper will tell you anything, don't hold your breath; the properties are plain accessors for the fields and this is the ctor:
OK, so the class itself doesn't unveil the mystery, but maybe applying it to one of our methods and then examining that will:
Nada. Tzifos. Nothing. At this point there is only one thing left to do: RTFM, and all is revealed:
Well I bet, like me, you guys (and gals) were hoping System.Reflection.ObfuscationAttribute would be a pseudo-custom attribute rather than just a marker for 3rd party tools, but not every journey leads to a treasure :-(
I guess I could be applying it to all my privates automatically since, as we know, custom attributes cost absolutely nothing, until you explicitly reflect on them.
(Just to get this out of my system: I think the term Attribute is an unfortunate choice by the .NET designers. "Annotation", "decoration", "declaration", “metadata” or anything else would have not only conveyed the purpose better, but would also not clash with the UML's existing use of the keyword "attribute" to mean fields/data_members of a class)
Look at the attribute with a decompiler:
[AttributeUsage(AttributeTargets.Delegate | (AttributeTargets.Parameter |
(AttributeTargets.Interface | (AttributeTargets.Event |
(AttributeTargets.Field | (AttributeTargets.Property |
(AttributeTargets.Method | (AttributeTargets.Enum |
(AttributeTargets.Struct | (AttributeTargets.Class |
AttributeTargets.Assembly))))))))),
AllowMultiple=true, Inherited=false), ComVisible(true)]
public sealed class ObfuscationAttribute : Attribute {
// Constructor
public ObfuscationAttribute();
// Properties
public bool ApplyToMembers;
public bool Excludet
public string Feature;
public bool StripAfterObfuscation;
// Fields
private bool mApplyToMembers;
private bool mExclude;
private string mFeature;
private bool mStripAfterObfuscation;
}
If you think drilling deeper will tell you anything, don't hold your breath; the properties are plain accessors for the fields and this is the ctor:
public ObfuscationAttribute(){
mStrip = true;
mExclude = true;
mApplyToMembers = true;
mFeature = "all";
}
OK, so the class itself doesn't unveil the mystery, but maybe applying it to one of our methods and then examining that will:
[System.Reflection.Obfuscation()]
public int ObfuscateThisPlease() {
int j = 6;
int i = 5 + j;
return (j - i);
}
.method public hidebysig instance int32 ObfuscateThisPlease() cil managed
{
.custom instance void [mscorlib]ObfuscationAttribute::.ctor()=(01 00 00 00)
// Code size 10 (0xa)
.maxstack 2
.locals init ([0] int32 j,
[1] int32 i)
IL_0000: ldc.i4.6
IL_0001: stloc.0
IL_0002: ldc.i4.5
IL_0003: ldloc.0
IL_0004: add
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: sub
IL_0009: ret
} // end of method Program::ObfuscateThisPlease
Nada. Tzifos. Nothing. At this point there is only one thing left to do: RTFM, and all is revealed:
"Instructs obfuscation tools to take the specified actions for an assembly, type, or member."
Well I bet, like me, you guys (and gals) were hoping System.Reflection.ObfuscationAttribute would be a pseudo-custom attribute rather than just a marker for 3rd party tools, but not every journey leads to a treasure :-(
I guess I could be applying it to all my privates automatically since, as we know, custom attributes cost absolutely nothing, until you explicitly reflect on them.
(Just to get this out of my system: I think the term Attribute is an unfortunate choice by the .NET designers. "Annotation", "decoration", "declaration", “metadata” or anything else would have not only conveyed the purpose better, but would also not clash with the UML's existing use of the keyword "attribute" to mean fields/data_members of a class)
Labels: VisualStudio, Whidbey
Sunday, January 16, 2005
On Friday (I almost broke my pattern and posted BLOTW then), Brad Adams announced a free .NET training series on Class Library design, kicking off with "Setting the Stage". I must admit it really does set the scene and there isn't any technical info in this one, but it does make me unable to wait for the next ones (make sure you read slides 11-14 for MSFT's business model as per BillG)! Definitely one for your bookmarks.
If you are after a quick WinForms tip, Cathi Gero has a cool one. Not only I've always liked the AutoTab feature as an end user, but as a developer I was not aware before of the highly configurable Control.SelectNextControl method.
And the lighter side of Project Management
If you are after a quick WinForms tip, Cathi Gero has a cool one. Not only I've always liked the AutoTab feature as an end user, but as a developer I was not aware before of the highly configurable Control.SelectNextControl method.
And the lighter side of Project Management
Labels: Links
Wednesday, January 12, 2005
This is a repost. The content appeared orginaly here, but I thought it deserved a post on its own rather than being at the bottom of an off (the main) topic entry.
[..] a demo I saw Don Box deliver at Tech Ed 2001 (in VB6) and TechEd 2004 (in Word Macro). So, in case you aren't aware of it, here is some VB6 code that always gets a nice reaction:
1. New VB6 "Standard EXE"
2. Project->References. Add:
Common Language Runtime Execuion Engine (mscoree)
Common Language Runtime Library (mscorlib)
3. Double-click on the form to get the Form_Load method (event handler)
4. Type in there the following 5 lines of code
5. Run->Start. The IDE breaks so you are in the debugger. View->Immediate Window
6. In the Immediate Window, type the following (line by line hitting return, don't just copy/paste)
That's it! You've just used a .NET Stack class in VB6 by hosting the runtime.
[..] a demo I saw Don Box deliver at Tech Ed 2001 (in VB6) and TechEd 2004 (in Word Macro). So, in case you aren't aware of it, here is some VB6 code that always gets a nice reaction:
1. New VB6 "Standard EXE"
2. Project->References. Add:
Common Language Runtime Execuion Engine (mscoree)
Common Language Runtime Library (mscorlib)
3. Double-click on the form to get the Form_Load method (event handler)
4. Type in there the following 5 lines of code
Dim crh As CorRuntimeHost
Dim ad As AppDomain
Dim oh As ObjectHandle
Dim o As Object
Stop
5. Run->Start. The IDE breaks so you are in the debugger. View->Immediate Window
6. In the Immediate Window, type the following (line by line hitting return, don't just copy/paste)
Set crh = New CorRuntimeHost
crh.Start
crh.CurrentDomain ad
Set oh = ad.CreateInstance("mscorlib", "System.Collections.Stack")
Set o = oh.Unwrap
o.Push "Rocks"
o.Push "NET "
o.Push "."
MsgBox o.Pop & o.Pop & o.Pop
That's it! You've just used a .NET Stack class in VB6 by hosting the runtime.
Labels: dot NET general
Tuesday, January 11, 2005
A great number of posts in the NETCF newsgroup are memory related. This is no surprise, given the constraints of devices (as opposed to the PC), and most posts somehow end with a variation on this tail question: "[...] is this a known memory leak with the CF?"
Given that there are plenty of CF resources to help you in this area, I thought I'd gather them up in a single place for future reference.
1. The first thing to do is make sure you are running the latest released CF version. Contrary to popular misconception, this is (today) CF 1.0 SP3. For CF version info (numbers, how to determine it, where to get it etc) please go here.
2. Doing the above is good regardless of anything else; the second thing to address is "Are you really having memory troubles?” Can you reproduce a sample where you get an OutOfMemoryException? If not, why do you think there is a memory leak! This is common to devs still new to the managed world, where resources are not reclaimed immediately after they have been used. A rule of thumb applies here: if an object you are using offers the Dispose method, call it when you have finished using the object.
3. So we've now reached the case where you can reproduce a sample that throws the OutOfMemoryException (or at the very least that is what your main app does). Before you start pointing fingers at the Garbage Collector, please understand how the GC works (note the significant differences compared to the Full Fx version i.e. not generational, code pitching etc). Once you've done that, understand some v1.0 issues and workarounds, including when to call GC.Collect
4. "Fine with all the theory, but how do I measure?" You have a number of options available (please use them):
- Call GC.GetTotalMemory(false)
- PInvoke GlobalMemoryStatus (FAQ 6.5)
- Monitor Perf Statistics/Counters (do follow the links from that blog entry)
- Device's control panel applet e.g. on WinCE emulator, Start->Settings->System look under the Memory tab for memory info and how to change the memory distribution (check out the FAQ on the WinCE memory division between Storage and Program memory)
5. For completeness, here is a link to an in-depth article on WinCE memory management. The main takeaway, if you are coming from a desktop background, is that each process in CE has a limit of 32MB virtual address space; so forget loading all those massive bitmaps in memory.
6. On very extremely rare occasions you may possibly observe a "Low Memory Dialog" rather than an OutOfMemoryException. This is the OOM dialog which shouldn't, but may, pop-up before a managed exception is thrown. That is an indication that you are stressing the system but, if you really want to, you can remove the OOM component from your device - assuming you have control of the image with Platform Builder (if you are in that situation, check out the SetOomEvent and registry entries).
7. Finally, if none of the links above take you to long documents with many numbers, go read Advanced Memory article on CF 2.0
Given that there are plenty of CF resources to help you in this area, I thought I'd gather them up in a single place for future reference.
1. The first thing to do is make sure you are running the latest released CF version. Contrary to popular misconception, this is (today) CF 1.0 SP3. For CF version info (numbers, how to determine it, where to get it etc) please go here.
2. Doing the above is good regardless of anything else; the second thing to address is "Are you really having memory troubles?” Can you reproduce a sample where you get an OutOfMemoryException? If not, why do you think there is a memory leak! This is common to devs still new to the managed world, where resources are not reclaimed immediately after they have been used. A rule of thumb applies here: if an object you are using offers the Dispose method, call it when you have finished using the object.
3. So we've now reached the case where you can reproduce a sample that throws the OutOfMemoryException (or at the very least that is what your main app does). Before you start pointing fingers at the Garbage Collector, please understand how the GC works (note the significant differences compared to the Full Fx version i.e. not generational, code pitching etc). Once you've done that, understand some v1.0 issues and workarounds, including when to call GC.Collect
4. "Fine with all the theory, but how do I measure?" You have a number of options available (please use them):
- Call GC.GetTotalMemory(false)
- PInvoke GlobalMemoryStatus (FAQ 6.5)
- Monitor Perf Statistics/Counters (do follow the links from that blog entry)
- Device's control panel applet e.g. on WinCE emulator, Start->Settings->System look under the Memory tab for memory info and how to change the memory distribution (check out the FAQ on the WinCE memory division between Storage and Program memory)
5. For completeness, here is a link to an in-depth article on WinCE memory management. The main takeaway, if you are coming from a desktop background, is that each process in CE has a limit of 32MB virtual address space; so forget loading all those massive bitmaps in memory.
6. On very extremely rare occasions you may possibly observe a "Low Memory Dialog" rather than an OutOfMemoryException. This is the OOM dialog which shouldn't, but may, pop-up before a managed exception is thrown. That is an indication that you are stressing the system but, if you really want to, you can remove the OOM component from your device - assuming you have control of the image with Platform Builder (if you are in that situation, check out the SetOomEvent and registry entries).
7. Finally, if none of the links above take you to long documents with many numbers, go read Advanced Memory article on CF 2.0
Labels: Mobile and Embedded
Sunday, January 09, 2005
I will not flood you with links like last time, but I must tell you that last week's winners have come back with killer posts; so revisit their blogs if you haven't already subscribed.
At the end of the first calendar week of 2005, why not download some tools (that I must admit not having played with yet)
-Check it out if you are working with process in WinCE and NETCF
-VS2005 Device Command Shell (a new tool that I bet will become very popular)
-Finally, subtle but important points about mixing operator overloading and inheritance.
At the end of the first calendar week of 2005, why not download some tools (that I must admit not having played with yet)
-Check it out if you are working with process in WinCE and NETCF
-VS2005 Device Command Shell (a new tool that I bet will become very popular)
-Finally, subtle but important points about mixing operator overloading and inheritance.
Labels: Links
Friday, January 07, 2005
Regular readers will recall the deployment feature for Smart Device projects that was cut after Beta 1. It has now been confirmed that the "Deploy to My Computer" feature will not be supported for RTM. However, there are some steps you can follow to get it working (it just won't be supported) and it is likely that in the future there will be a powertoy to do the steps for you.
If you want more details on the feature I am talking about, and more importantly want to follow the steps to get "Deploy to My Computer" working today with the November CTP, please visit ladybug.
Below is a copy of the steps (which I can confirm work... on my setup anyway:-).
This is courtesy of Kei Amos:
UPDATE: For Beta 2, also see this thread
If you want more details on the feature I am talking about, and more importantly want to follow the steps to get "Deploy to My Computer" working today with the November CTP, please visit ladybug.
Below is a copy of the steps (which I can confirm work... on my setup anyway:-).
This is courtesy of Kei Amos:
Enabling deployment of managed applications to the desktop rather than a device:
This is a great productivity enhancement for application development, when you deploy often.
Note: Applications that use device-specific apps will not run properly on the desktop, and controls will render as desktop controls.
INSTRUCTIONS
1. In Visual Studio select Tools/Options, and then select Device Tools/Devices from the tree.
2. In the top combo box, select the platform that you want to add desktop deployment to. You’ll need to do this for each platform you want to use.
3. Select one of the devices, (it doesn’t matter which one) and click the Save As… button. Save as “My Computer”. If you’ve already done this for a platform, you’ll need to save subsequent devices with slightly different names (like “My Computer2”)
4. Close VS and open your %USERPROFILE%\Local Settings\Application Data\Microsoft\CoreCon\1.0\conman_ds_platform.xsl file in a text editor.
5. Find the <DEVICE …> element corresponding to the device you created and add the node (i.e. search for “My Computer” to find the correct node.)
<PROPERTY ID="IsDesktopDevice" Name="IsDesktopDevice">true</PROPERTY>
Place it right after the first <PROPERTYCONTAINER> tag.
6. Save conman_ds_platform.xsl and restart VS.
Now when you deploy, you can select “My Computer” from the deploy dialog.
UPDATE: For Beta 2, also see this thread
Labels: Mobile and Embedded
Thursday, January 06, 2005
As the sample I promised, I have written a visualizer for System.String. Given a string variable, it will show the bytes corresponding to that string based on the various encodings. The inspiration for it was the cry that a friend of mine got from their QA team recently regarding an app they have that "Doesn't work on a Chinese OS!".
To create it, we need a class library project that references Microsoft.VisualStudio.DebuggerVisualizers.dll and we add the following code:
1. Declare the attribute:
The above is all you need to enable the new menu item when you hover over a string variable (or in the Autos window). In the IDE, the menu looks something like this. Note how VS2005 gives us out of the box the HTML, XML and TEXT visualisers.
2. The code that runs when the "Encoding Viewer" menuitem is clicked, is in your class:
To create it, we need a class library project that references Microsoft.VisualStudio.DebuggerVisualizers.dll and we add the following code:
1. Declare the attribute:
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(EncodingVisualizer.StringBytes),
Target = typeof(System.String),
Description = "Encoding Viewer")]
The above is all you need to enable the new menu item when you hover over a string variable (or in the Autos window). In the IDE, the menu looks something like this. Note how VS2005 gives us out of the box the HTML, XML and TEXT visualisers.
2. The code that runs when the "Encoding Viewer" menuitem is clicked, is in your class:
using Microsoft.VisualStudio.DebuggerVisualizers;Naturally, you need a form frmStringBytes whose visual design looks like this; the constructor of the form does the work and is straightforward:
namespace EncodingVisualizer {
public class StringBytes : DialogDebuggerVisualizer {
protected override void Show(IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider) {
string s = (string)objectProvider.GetObject();
frmStringBytes f = new frmStringBytes(s);
f.ShowDialog();
}
}
}
public frmStringBytes(string aString)You may download the dll and place it in the right place as discussed before.
: this() {
txtExpression.Text = aString;
string s;
byte[] arr;
arr = System.Text.Encoding.ASCII.GetBytes(aString);
s = "ASCII = " + BitConverter.ToString(arr);
s += "\r\n\r\n";
arr = System.Text.Encoding.Unicode.GetBytes(aString);
s += "Unicode = " + BitConverter.ToString(arr);
s += "\r\n\r\n";
arr = System.Text.Encoding.Default.GetBytes(aString);
s += "Default = " + BitConverter.ToString(arr) + "\r\n";
// Do other encodings here e.g UTF7, UTF8, UTF32 etc
txtValue.Text = s;
}
Labels: VisualStudio, Whidbey
Wednesday, January 05, 2005
The latest Service Pack 3 for the .NET Compact Framework is now released as an MSI (via Tom Krueger). It was previously available as a QFE only.
For version number and full fix list please visit my previous announcement of the QFE release.
For history of NETCF version numbers and how to determine what version you are running see the wiki page.
For version number and full fix list please visit my previous announcement of the QFE release.
For history of NETCF version numbers and how to determine what version you are running see the wiki page.
Labels: Mobile and Embedded
Apart from Tracepoints (as hinted at the last sentence of that post), the most exciting debugging enhancement in Whidbey is the Debugger Visualizer support. If you are already familiar with VS2005 Debugger Visualizers, here you'll find what has changed with the latest Community Technology Preview (btw, the Dec is not the latest CTP from a framework version perspective, the Nov one is). If you are not familiar with the feature, I suggest you follow these links [ 1 , 2 , 3 , 4 ] and note the changes from previous versions detailed below:
1. The assembly reference must be to:
2. The
3. Your class that implemented the
That's all. If you didn't know about Debugger Visualisers and have downloaded the Nov CTP, follow the links at the top (and below), download their samples, make the appropriate changes and have fun!
Next time I'll implement a DebuggerVisualizer (not an Image Visualizer, which you can get here, here and here) so you have a complete sample to download.
1. The assembly reference must be to:
Microsoft.VisualStudio.DebuggerVisualizers2. The
DebuggerVisualizer attribute ctor doesn't need the 3rd param i.e. delete the VisualizerUIType parameter as all visualizers are modal now.3. Your class that implemented the
Show method of IDebugVisualizer should now inherit from DialogDebugVisualizer and override the Show method; the signature for this now is:void Show(IDialogVisualizerService, IVisualizerObjectProvider)Of course, you need to imports/using System.Diagnostics and Microsoft.VisualStudio.DebuggerVisualizers; the location for visualizers (assemblies/dlls) is still the same: "My Documents\Visual Studio\Visualizers" or "[VS8]\Common7\Packages\Debugger\Visualizers"
That's all. If you didn't know about Debugger Visualisers and have downloaded the Nov CTP, follow the links at the top (and below), download their samples, make the appropriate changes and have fun!
Next time I'll implement a DebuggerVisualizer (not an Image Visualizer, which you can get here, here and here) so you have a complete sample to download.
Labels: VisualStudio, Whidbey
Sunday, January 02, 2005
-Like last week, it is a (almost) new blogger that headlines BLOTW, an MSFTie no less, Scott Holden. Read all 5 posts he makes in his first week including the one where we learn that the GC threshold in CF 2.0 changes from 750KB to 1MB.
-Not technical, but it caught my attention (and read it to the end following all links etc). Have a look and decide where you stand. I am not quite so sure...
-Some A-list bloggers claim that if you haven't posted for a month you are worthy of un-subscription, I don't buy that. Steven Pratscner's last post was over 4 months ago; had I unsubscribed I would have missed this most informative entry.
-How do you calculate the size of a directory?
-Not sure how you'll use this knowledge but if you like knowing what goes on under the covers when you set a breakpoint, this entry is for you.
-This BLOTW is the longest I've done, but still, I must point you to a time waster (via Tech Blender). I managed to write "THE MOTH" but the closest I got to my name was "DA IE MO H"
-Not technical, but it caught my attention (and read it to the end following all links etc). Have a look and decide where you stand. I am not quite so sure...
-Some A-list bloggers claim that if you haven't posted for a month you are worthy of un-subscription, I don't buy that. Steven Pratscner's last post was over 4 months ago; had I unsubscribed I would have missed this most informative entry.
-How do you calculate the size of a directory?
-Not sure how you'll use this knowledge but if you like knowing what goes on under the covers when you set a breakpoint, this entry is for you.
-This BLOTW is the longest I've done, but still, I must point you to a time waster (via Tech Blender). I managed to write "THE MOTH" but the closest I got to my name was "DA IE MO H"
Labels: Links
Saturday, January 01, 2005
I don't like “pointing to myself”, but reflection is a good thing I guess. So, in chronological order, here are some of my favorite blog entries that I posted in 2004:
01. If you are changing thread priorities in your NETCF apps without being aware of these facts...good luck!
02. Everything about .NET Global Exception Handling is either in these 3 posts or in the links they point to: .NET 1.1, NETCF 1.0, .NET 2.0 (full & compact)
03. Whidbey's answer to UML class diagrams and where it falls short
04. So you are developing for both full & compact framework; are you doing it like this or like that?
05. Inter-Process Communication options with CF on WinCE; if it's not there, it doesn't exist
06. ALL links about serial comms (RS232) with .NET are here
07. VB2005 along with My brings Application Level events with a custom sub main. Use it *all* from C#
08. Control.Invoke today and tomorrow
09. More of a newsgroup support entry, but who says plain useful posts cannot be on my favorite list :-)
10. Generics in the Compact Framework (and not only)
11. BackgroundWorker today, tomorrow, full and compact frameworks: enough said
Thanks for reading... stay subscribed for an exciting 2005. As an aside, am I the only sad geek who associates the word "2005" with VS2005 ;-)
01. If you are changing thread priorities in your NETCF apps without being aware of these facts...good luck!
02. Everything about .NET Global Exception Handling is either in these 3 posts or in the links they point to: .NET 1.1, NETCF 1.0, .NET 2.0 (full & compact)
03. Whidbey's answer to UML class diagrams and where it falls short
04. So you are developing for both full & compact framework; are you doing it like this or like that?
05. Inter-Process Communication options with CF on WinCE; if it's not there, it doesn't exist
06. ALL links about serial comms (RS232) with .NET are here
07. VB2005 along with My brings Application Level events with a custom sub main. Use it *all* from C#
08. Control.Invoke today and tomorrow
09. More of a newsgroup support entry, but who says plain useful posts cannot be on my favorite list :-)
10. Generics in the Compact Framework (and not only)
11. BackgroundWorker today, tomorrow, full and compact frameworks: enough said
Thanks for reading... stay subscribed for an exciting 2005. As an aside, am I the only sad geek who associates the word "2005" with VS2005 ;-)
Labels: Personal
Copyright © Daniel Moth


