CF with Delphi

Sun, February 27, 2005, 07:41 AM under MobileAndEmbedded
I would like CF development to be accessible to *everyone*. No personal gain in that statement (I've always had an MSDN universal subscription and I don't plan, in the near future, to write in anything other than C# and VB), I just want the platform to gain more developers/users.

It is sad that there is no SDK for CF 1.0 and that VS.NET 2003 Professional and above is required. Even though CF 2.0 comes with an SDK and VS2005 Standard is adequate, I am still not happy that the Express editions will not support Smart Device projects.

On the programming language front, dotnet is about multiple languages being able to target the platform (20+ on the desktop). On the other hand, CF only allows C# and VB.NET! No J#, no managed C++ etc. If you are thinking "it all compiles down to IL at the end of the day", unfortunately that is not enough: some IL instructions such as localloc and calli are not supported and design time support is more complex.

So, in the context of the above, I was disappointed to read this post on the Delphi blog (via Tim Anderson).

Will an MSFT reply be forthcoming?

ThreadPool

Wed, February 23, 2005, 02:57 PM under MobileAndEmbedded
No doubt you are familiar with the System.Threading.ThreadPool (if not, go learn about it now!). The Compact Framework implementation only offers a single method: QueueUserWorkItem(WaitCallback, Object). Basically, every time you call this method it will call you back on a different thread, passing back to you the state object you gave it, so you can run your background work. Once the background work is finished (i.e. the method returns), the thread is then either reused in a future call or is removed from the pool (after a undefined interval). The advantage over explicitly creating threads is obvious in such a thread-reuse scenario (less context switching, no thread creation/destruction overhead each time, ease of use).

Internally, the NETCF ThreadPool is built on the System.Threading.Timer (whose core implementation is in native code). In other words starting a one shot timer with dueTime of 0 is the same as queuing a work item with the ThreadPool. Clearly using the ThreadPool is the preferred choice (in other words don't use the Threading.Timer just for going async, rather use it in scenarios where timing is truly required).

Apart from the different implementations, the desktop and CF ThreadPool have other differences.

1. The documentation states that explicitly using a thread is a better alternative to the ThreadPool for lengthy operations i.e. use the ThreadPool for short-lived tasks. One of the reasons it advises this is because the desktop implementation has a ThreadPool limit of 25 per process (so, for example, you can imagine deadlock situations if you starve the ThreadPool of its 25 threads and e.g. two of them are waiting to acquire the same resource). However, the NETCF 1.0 ThreadPool has a limit of 256 (treat that as if there was no limit; for a laugh, I tried testing the limit and my device stopped responding around ~150). Note that CF 2.0 rectifies this by setting the limit to 25, bringing parity with the desktop. On the desktop with .NET 1.1 you can change it if you really try hard and with .NET 2.0 there is even a method (SetMaxThreads). I am not sure if we will see this method in the CF 2.0 RTM, but for the November CTP you can control the number of threads via the registry: HKLM\Software\Microsoft\.NETCompactFramework\ThreadPool\MaxThreads

2. The desktop's ThreadPool threads are all background. Since the CF 1.0 does not support background threads, the difference is obvious. As a reminder, a non-background thread can keep your process up even if the main (UI) thread has exited. Since CF 2.0 supports Thread.IsBackground, the ThreadPool threads will return true for that property.

3. ThreadPool threads, like other managed threads, are created at the default priority of Normal (251 in WinCE terms). I have discussed previously about "Threads and ThreadPriority with the .NET Compact Framework". If (against my advice in that post) you change the priority of ThreadPool threads (which btw can only be done in the callback), you will find that the priority may not be reverted when the thread is returned to the ThreadPool (MSFT quote). In other words, future uses of the ThreadPool could run on that thread with whatever priority you gave it in a different context (dangerous!). This is not true for the Full Framework and, fortunately, CF 2.0 brings parity with the desktop.

So we can see all the differences between CF 1.0 and Full Fx 1.1, but we also see how CF 2.0 eliminates them.

Finally, CF 1.0 does not support Control.BeginInvoke but CF 2.0, like the desktop, does. BeginInvoke indeed uses threads from the ThreadPool on both platforms.

ListView with scroll events and TopItem

Tue, February 22, 2005, 02:09 PM under MobileAndEmbedded
Two years ago I asked the question:
"I cannot find an event to catch when the user scrolls the scrollbar? The goal is to detect when the listview is scrolled and then get all visible items (or just the top one and work my way down since I know how many can be visible at a time) and do some function..."
I then replied to my own post.

The simple idea of overlaying the listview with a vscrollbar works great and is an important technique for CF lists with a large number of items (for memory and performance improvements). What I am trying to say is that, rather than populate your list with XXX number of items, you need only populate the visible (e.g. 8-16) items and when the user scrolls down populate accordingly the remainder (since you know the top index and the number of visible items at any one time).

The same principle, but with a twist, applies when the listviewitems need to be refreshed/updated every so often. E.g. my listviews get populated with information retrieved from the network. By knowing which items are visible, I avoid refreshing the ones that are not, resulting in faster user interaction and less noise on the network. By also wrapping the refresh timer into the container control, the rest of the client code is oblivious to how the list gets populated.

Finally, you could offer explicit pageup/pagedown buttons (since you are in programmatic control of the scrolling). A screen shot of what such a listview looks like see this (the statusbar of that screenshot is a whole different story :-).

Enjoy the code from the link at the top of this post and if you need the same for a ListControl rather than a listview, follow the link from here.

How do I serve webpages from NETCF?

Mon, February 21, 2005, 09:03 AM under MobileAndEmbedded
Over the last 2-3 weeks I have discussed on 3 completely separate occasions the subject of serving web pages from a CF application on a Windows CE device. Since ASP.NET is not supported on the Compact Framework, the question I get is "how to" and my answer is typically along these lines:

There are 3+1 options
1. Native Only
2. Managed Only
3. Hybrid
4. Wait for CF 3.0 (?)

1. The first option is basically not an option if you are determined to leverage your business logic, which is already written in C# or VB.NET. However, I always mention it because I think it is important to understand what the out-of-the-box options are on Windows CE. You can find them here.

2. The second option basically means writing your own web server (and hence not taking advantage of IIS on WinCE). This either makes faces drop ("Are you serious?") or produces smiles ("I am a control freak anyway so having complete command of how the web server works sounds great!"). Either way, you don't have to start from scratch, as others have been there before (use them as inspiration or just rip off their implementations).
a) Port cassini
b) Use the results of the Monash project
c) Port the ASP.NET MONO implementation (not aware of any *public* project that has achieved it, but there are some guys that have done it (ended up at ~1300KB) and if they want to go public with it I am sure they will - I cannot say anything else, I'm afraid)

3. If you followed my link when discussing the first option, you know that on WinCE you typically write an ISAPI extension for serving pages; imagine if from the ISAPI extension entry point (HttpExtensionProc) you could start talking to a managed dll that did the work for generating and returning the pages. Alas, unlike the desktop, hosting the runtime is not an option with NETCF. So what is it that I always offer as a poor alternative for hosting the runtime? Inter-Process Communication! So, to summarise the hybrid approach with CF 1.0/2.0: Write some C code that seats between IIS and a managed exe communicating via any IPC mechanism you see fit.

4. This is not a serious option for two reasons: Who in their right mind will wait for CF 3.0 when even CF 2.0 is not released yet (does anybody work for a company that looks that far into the future)? The second reason this is not a serious option is because nobody knows what CF 3.0 will offer! My hope is that the CF team will listen to requests on allowing us to host the CLR (this will make option 3 a breeze) or even better offer ASP.NETcf (and then I woke up :-)

Expect to read more on this topic here in the future, as I am looking at this feature for one of our products.

Blog link of the week 07

Sun, February 20, 2005, 03:04 PM under Links
3 days ago a thread started on an internal list (which is still going) whose subject was enough to catch my attention (paraphrased here):
Richard Grimes gives up on .NET

On one side I am shocked, on the other his justification is not convincing (to me anyway). Either way it does make you stop and think so I reckon it deserves BLOTW even if it isn't strictly a blog link.

Oh, and if like Frans you are asking "Who's Richard Grimes", here is a small example of his work (Workshop on Fusion).

Richard better have something else planned. I make it a point to never leave something old without having something new lined up: be it a car/house/job/PC/woman etc... only joking about that last one :-D

Filter Exceptions

Thu, February 17, 2005, 06:31 PM under Whidbey | VisualStudio
Right click on the Output window in VS.NET and you get a lame contextmenu with 3 options: "Copy", "Clear All" and "Go To Error/Tag".

In April 2002 I requested that we are given the ability to exclude first chance exceptions from the output window.

Finally, 3 years later we get what I asked for :-)
Unchecking the "Exceptions" menuitem should turn first chance exceptions off.

It also looks like the Debug->Exceptions dialog has had a face lift...

Hack: Prevent Enumerator Throwing

Wed, February 16, 2005, 12:01 PM under dotNET
Dim i As Int32
Dim k As Int32 = mCol.Count
For i = 0 To mCol.Count - 1
Me.MethodThat_May_ResultInRemovalFromCol()

If k > mCol.Count Then
i -= 1
k = mCol.Count
End If
If k <= i + 1 Then
Exit For
End If
Next i
Years ago I upgraded some nasty VB6 code that, amongst other things, used the Collection class. The VB.NET Collection object allows removals from it while iterating. If you upgrade it to ArrayList, though, (apart from making changes to reflect the 0 index base), you soon find that ArrayList forbids removing items while iterating. At the time I came up with the above smelly hack. Due to recent refactorings the design/code has been modified, so I am capturing the hack here for posterity...

PS I upgraded Collection to ArrayList for performance reasons
PS2 Locking the collection is irrelevant here
PS3 I am aware of Synchronized - I don't like it
PS4 The real solution is not to remove while iterating; it is bad design.

Netmodules revisited

Tue, February 15, 2005, 01:25 PM under MobileAndEmbedded
Alternative title: "Discovery of the day, link.exe"

Recall how at the Beta 1 timeframe we saw CF 2.0 add support for multi-file assemblies? If not, please go and read it, as the content here builds on that (here based on November CTP).

a) Follow steps 1, 2 and 3 from that post (adjusting the path to [drive letter]\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\CompactFramework\2.0\Debugger\BCL).

b) Change step 4 by typing /t:module just before ProgramMixed.cs
You now have two files (Form1Mixed.netmodule & ProgramMixed.netmodule) but, instead of one of them being an exe and the other a netmodule, they are both netmodules. Recall from step 5 that running the exe would work only if the netmodule accompanied the exe (hence the talk of multi-file assemblies).

c) Now, enter the following at the command line:
link /LTCG /verbose /entry:MixedLanguages.Program.Main /out:SingleFile.exe Form1Mixed.netmodule ProgramMixed.netmodule /subsystem:windows

The result is a single executable that contains the IL from both netmodules (that you recall were written in two different languages)! And we didn't even have to use ilmerge.

[This blog entry was inspired by this post]

Blog link of the week 06

Sun, February 13, 2005, 03:59 PM under Links
I hope you are not waiting for BLOTW to find out about the Indigo news from VSLive… or about Java creator’s anti-dotnet comments (and the numerous responses).

Go understand the nice post on cctors (even though you should know by now about beforefieldinit).

It’s not everyday I learn about a new Whidbey feature (don’t take that the wrong way, it’s true) so I was pleasantly surprised this week with linkedConfiguration

Are you looking for a formal explanation to switch to .NET

There are better uses of your cpu, but this is funny (via Sahil)

Brighton Winter Awards Ceremony

Fri, February 11, 2005, 04:40 PM under Personal
I was there! Not something to brag about (and I am not), but I had to be there to watch Jenny receive her degree. After 4 years of non-MSFT development I managed to convert her to .NET and that is what she focused on during her MSc course. By the way, she is not looking for a job anymore; got one a month ago and it is going well.

Anyway, after around 11 hours in town drinking and celebrating, I wonder how badly hangover I’ll be tomorrow. Have you tried programming while drunk? It is interesting, and I must admit VB seems easier in that state: you just type and it corrects silly mistakes (that you don’t do when sober) as well as point errors much earlier in the process (background compiler has always been my number one VB feature).

Just noticed that I am rambling and I promised myself not to do that on my blog… too much… so goodnight folks... talk to you on Sunday as usual.