Explicit assignment slower

Mon, May 30, 2005, 09:58 AM under dotNET
As you know, in VB variables do not need to be initialised, as they always get the default value for the variable type in question, e.g.
Dim b As Boolean 'b is already initialised to False

In C-based languages (inc. C#) this does not apply; you must initialise the variable before you use it, e.g.
bool b = false;

The above is the reason we cannot have ByOut in VB (only ByVal and ByRef) whereas C# has both ref and out (ByVal is implied by omission).

I have seen VB code that follows the C-style and there are two common reasons for doing so; one is to be explicit and the other is because of a C-based upbringing. The question is what IL will the VB compiler generate, faced with code that differs only by explicit assignment (we know it is pretty crap at optimising the simplest of scenarios, so we don't go in with our hopes high).

Given these two methods (and assuming a private method GetNumber):
    Public Sub VBStyle()
Dim i As Int32
i = GetANumber()
End Sub

Public Sub CsStyle()
Dim i As Int32 = 0
i = GetANumber()
End Sub
I can tell you that the VB compiler generates slower code for the second scenario (I have to say if you have a bottleneck in your project, cases like this will not be it, but it is still good to know :-).

Here is the corresponding IL:
.method public instance void  VBStyle() cil managed
// Code size 8 (0x8)
.maxstack 1
.locals init ([0] int32 i)
IL_0000: ldarg.0
IL_0001: callvirt instance int32 VBWinApp.Class3::GetANumber()
IL_0006: stloc.0
IL_0007: ret
} // end of method Class3::VBStyle

.method public instance void CsStyle() cil managed
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] int32 i)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldarg.0
IL_0003: callvirt instance int32 VBWinApp.Class3::GetANumber()
IL_0008: stloc.0
IL_0009: ret
} // end of method Class3::CsStyle
Needless to say that the C# version closely reflects the first version (it is even better, since it uses a call rather than a callvirt - but that is a different story...).

Blog link of the week 21

Sun, May 29, 2005, 03:38 PM under Links
It's a known fact that while the VB compiler team focuses on VB6 compatibility, the C# compiler team focuses on optimisation (funny that, for a compiler team); so I was not surprised with this.

Robert points to updates on the Windows Mobile Migration FAQ for developers

I echo *every* single sentence on this post on signing in VS2005

Looking at the number of comments, you don't need me to tell you about it but... here is some info on tabbed browsing implementation in IE7

Microsoft's view on modelling makes an interesting read, e.g. "What about UML" (via)

Funny and so true (I have used at least half of them in the past :-)

Out of Country

Sun, May 22, 2005, 10:14 PM under Personal
Do not expect anything on this blog (or any online activity, emails etc) for the next week.

In about 25 minutes I am leaving for a business trip to the most Northern parts of Europe. In 5 days we endeavour to visit 4 countries (Denmark, Sweden, Finland and Norway) and more specifically 9 sites (5 immediate customers and 4 end users).

… just as I was recovering from the Vegas jetlag…

Blog link of the week 20

Sun, May 22, 2005, 02:45 PM under Links
Expect this technique to be used extensively with NETCF 2.0. Sure there was an easy workaround for obtaining the Handle, but pinvoking APIs with callbacks was impossible (without a native helper dll) since DllImport in CF 1.0 does not support delegates in the signature. Enjoy Subclassing controls in CF 2.0

I know I will be referring to these steps for removing SS from VS projects

Now I'll never forget the OSI layers "Please Do Not Throw Salami Pizza Away" (via)

CF COM Interop #1 FAQ

Fri, May 20, 2005, 02:15 PM under MobileAndEmbedded
Now that NETCF 2.0 supports COM Interop (for CF 1.0 your best bet is 3rd party support), there is a FAQ emerging.

Q: I have a native/C++ exe/process and cannot get it to talk to my managed/C#/VB dll/class library. What's wrong?
A: As indicated last year, this is not supported.

To help Google get you here, I will use various phraseologies that all indicate the same thing.

You can call native COM components from managed code, as long as it is from a managed exe - VS will generate the RCW (Remote Callable Wraper) for you. Once you have activated native COM objects from managed code, they can call you back; so in that sense - and that sense only - CCW (COM Callable Wrappers) are supported.

You cannot activate (or register) managed objects through COM. Regasm.exe that the full framework supports is not available. Forget doing a CoCreate on your managed objects.

If you think about the last statement it makes sense, since runtime hosting of the NETCF CLR is not supported; how could you start a native process that "talked" to a managed library (dll)?

Incidentally, if you must communicate from native code to managed code and since you cannot do that in the same process, consider one of the IPC mechanisms available on WinCE.

While we are on the subject of NETCF 2.0 COM Interop limitations, allow me to quote from one of Richard Greenberg's slides from MEDC:
"Only MTAs (multi-threaded apartments) are supported and there are no custom marshalers or auto-generated Class Interfaces."

My Project Properties

Thu, May 19, 2005, 03:23 PM under Whidbey | VisualStudio
With Visual studio 2005 the contents structure of Solution Explorer has changed. Even with VS2003 I always had the "Project->Show All Files" option turned on but with VS2005 it is essential (by default, they hide more than what they show!).

The main change is that under each project there is a folder (just above "References"). Amongst other things it contains the AssemblyInfo file (that previously was with all the other files). If you open the project properties and go to the "Application" tab you'll find a button called "Assembly Information" that brings up a dialog showing the AssemblyInfo values. If for whatever reason you’d prefer the AssemblyInfo file to live with the other code files, then simply drag it out; the project properties will still find it :-)

Under the same folder you'll find a Resources.resx file (and its dependent Resources.Designer). Again, you can manipulate this via the project properties and specifically the "Resources" tab. It is these files that enable My.Resources (and the Resources class in C#) wrapping the System.Resources.ResourceManager. If for whatever reason you’d rather not have these files, then right click on them and delete them (you can always regenerate them via the project properties “Resources” tab).

All of the above is applicable to projects targeting PC or devices and is true for both VB and C#. Of course, keeping the name of the folder the same for both languages would be sacrilege so in VB it is called "My Project" and in C# it is called "Properties".

Furthermore, only for desktop projects (you didn't think we'd have it all in the Compact Framework did you?), the folder also contains Settings.settings (and its dependent Settings.Designer) files. As you guessed, these enable the editing of settings in the project properties based on an auto-generated Settings (My.Settings in VB) class that inherits from System.Configuration.ApplicationSettingsBase). If for whatever reason you’d rather not have these files, then right click on them and delete them (you can always regenerate them via the project properties “Settings” tab).

Finally, only for VB desktop projects, the "My Project" directory contains the files: Application.myapp, Application.Designer.vb and ApplicationEvents.vb. These are responsible for the new startup model and application level events, which we looked at in the Beta 1 timeframe (it has changed slightly but the majority is identical and the changes are mostly cosmetic e.g. the option is now called "Enable Application Framework" rather than "Startup with custom Sub Main"). If you don’t want the ApplicationEvents.vb file, then simply delete it (you can always regenerate it via the button “View Application Events” under the Project->Properties Application tab). Whatever you do, *do not* delete the other two vb files; with Beta 2 at least, nasty things can happen (things that force you to use Task Manager -> End Task)! Having just said that, those two files are also present in Class Library projects even though the relevant project properties areas are disabled (!). In the class library case it seems safe to delete them.

Class Designer news

Wed, May 18, 2005, 02:57 PM under Whidbey | VisualStudio
Due to numerous fundamental omissions, the Class Designer has a long way to go before it can fully compete with existing modelling tools (although it already beats them hands down in some areas). The only devs who don’t see that are quite frankly those that haven’t used on a regular basis UML tools before (either due to not having the chance to do so _or_ because they tried and quickly quit due to the high UML learning curve).

Today, two posts in the class designer forums renewed my faith in the tool big time.
1) Full signature support in RTM (look for contribution by Ramesh on 18 May)
2) A cool open project that seamlessly adds a whole bunch of features (including showing all fields as associations for selected types). Shame about the gotdotnet choice Dmitriy, but you can’t have it all I guess :-)

Good stuff, thanks guys!

NoWarn or VB compiler options

Tue, May 17, 2005, 12:44 PM under Whidbey | VisualStudio
With VS2005, if you open the project properties of a VB project and select the "Compile" tab, you'll see a bunch of options.

[digression]Why did the VB team call it the "Compile" tab, whereas the C# team call it the "Build" tab? Although it is a rhetorical question, I'll answer it: Because the two teams do things differently for the sake of it! Consistency between the two is not only not a requirement, but probably looks bad at review time, so they avoid consistency as much as possible. Anyway...[/digression]

So you are on the "Compile" tab and you can choose between the None|Warning|Error notifications for each of the following 9 conditions (we'll see in a moment what the 5-digit numbers are after each one):
1. Implicit Conversion - 41999, 42016
2. Late binding call could fail at run time - 42017,42018,42019,42032,42036
3. Implicit type; call could fail at run time - 42020,42021,42022
4. Use of variable prior to assignment - 42030,42104,42108,42109
5. Function/Operator without return value - 42105,42106,42107
6. Unused local variable - 42024
7. Instance variable accesses shared member - 42025
8. Recursive operator or property access - 41998,42004,42026
9. Duplicate or overlapping catch blocks - 42029,42031

I will not explain each one here, because I hope they are self-explanatory. When you turn On Option Explicit and Strict you'll see that the top 3 are automatically set to Error.

So that leaves the remainder 6. I advise you to set the last 5 to Error; I cannot think of a reason why you would not want to correct issues caught by the compiler - if you have come across a reason, please debate it with me.

So we are now left with Use of variable prior to assignment: Set this to None. The feature is not complete and I have left comments here and submitted the bug here, to no effect. I guess you could turn it on and see if it has caught anything useful and, after wading through a sea of false positives, turn it off again. But this is literally a waste of time.

Finally, let's see what the 5-digit numbers are about. The VB compiler has more than 9 settings; in fact it has at least 24 (represented by the 5 digit numbers). When you make changes to the project properties' tab as discussed above, if you open the vbproj in notepad you'll find a NoWarn tag. Within that tag the series of numbers represents your choices. By enabling one warning at a time, saving and then examining the file, you'll come up with the mapping I have above, e.g.:
The second line instructs the compiler not to bother warning us about possible null reference exceptions. The first line tells it to set all other warnings to errors (this is separate to the "TreatWarningsAsErrors" tag that acts independently on a more generic level).

One question still remains. Why, in some cases, there is more than one number corresponding to a setting? The answer must be because there is finer grained control available that the VB project properties dialog is not offering (in fact, in the C# project properties you can freely enter the corresponding set of C# compiler numbers). Yet another tradeoff between simplicity (i.e. nice UI) and flexibility (i.e. full control).

Compact Framework Unit Testing

Mon, May 16, 2005, 12:49 PM under MobileAndEmbedded
Do Smart Device Projects (i.e. Compact Framework projects) support unit testing as offered by Visual Studio 2005?

1. In a CF project write the following method:
public Int32 GetBuildVersionPart(){
return System.Environment.Version.Build;
2. Right click on the method and choose "Create Tests...", choose C# and OK, choose default name and OK

3. Set the newly created project as startup project (via context menu)

4. Go to the test method and change the following line:
int expected = 0;
int expected = 50215;

5. Comment out the Assert.Inconclusive line

6. Run the project

7. Observe: The PPC emulator starts, which is promising, but unfortunately the unit test passes :-(
It would not pass if it was running against the CF, as the build number is 5056 (the full framework build number for Beta 2 is 50215).

Unit testing is not supported by CF projects and instead the tests get retargeted to the full framework (much like Deploy to My Computer).

For an open source project that supports unit tests running on the device, see CFNUnitBridge from Trey

Blog link of the week 19

Sun, May 15, 2005, 03:23 PM under Links
Q: How long should a tech book be? A: 450 pages. Do you disagree?

Application Blocks for the Compact Framework

Quote of the week: Attributes are like tattoos - static and permanent

I hope the C# team follow the link from there and implement the only item I miss when coding in C#: Background Compiler

Popular tool re-implemented in unmanaged code for perf reasons! (via this)

Last day in Vegas

Fri, May 13, 2005, 08:51 AM under Random
MEDC came to its conclusion yesterday and today is my last day in Vegas.

Yesterday was a good day: Alex_F gave his all inclusive COM interop talk; David_K/Mark_I held their debugging session and Roman_B on NETCF performance were simply great. Also, Chris_T announced our latest SDF release.

Reflecting on the conference now that it has ended, there were a few things here and there that were new to me but, due to our close links with MSFT and the numerous Whidbey drops I've played with over the past year, I must say that most content was familiar. How about some level 500 sessions next year?

However, that is not the main takeaway as the most important benefit was meeting tens of MSFT people and it was great to put a face to a name and equally beneficial meeting new MSFT names/faces. In the same vain, I got a chance to meet most of the MVP community and quite frankly that is what it is all about. Apart from a handful of MVPs that couldn't make it there and a few MSFT people that I (unluckily) just didn't run into, from a networking perspective this conference met my expectations 101% :-D

Soooo... I am catching a flight to San Francisco later on and after a brief stop there it is back to Blighty... I was going to go into how much I "deposited" at the casino but I think this is a good point to stop the diary-style blogging and go back to the technical focus starting from the next blog entry.


Wednesday, conclusion to the day

Wed, May 11, 2005, 11:13 PM under Random
After the first slot it was pretty much downhill... A very bad presentation from what was very obviously a marketeer using somebody else's slides and code... A session where the title had nothing to do with the content... A one hour marathon where there was a single message and not much more content...

It's not all doom and gloom though... I had an hour supporting the NETCF booth in the exhibition area and another at the MVP cabana (which meant I only caught 30 minutes of what was a cool introduction to MSMQ by Andy Wigley) and had some interesting conversations there...

After a private do where we met with the interesting MapPoint team, came the highlight of the day: "Blue Man Group"! Words cannot describe the show... at the end I got a photo with one of them (and here is Paul with another)...

Wednesday start and a photo

Wed, May 11, 2005, 09:49 AM under Random
First session today was Ginny's... very good show and here is a photo after the event

(Alex Y, Alex F, Ginny C, Daniel M, Peter F)

Very long first MEDC day

Wed, May 11, 2005, 12:10 AM under Random
Keynote by William Gates was *packed*! Windows Mobile 5.0 codename Magneto finally released. Search for links as the news should be all over the place by now...

Following that, an interesting panel discussion on building mobile applications went well...

One of the highlights of the day was lunch with members of the NETCF and VSD teams... I must have spent an hour complaining about bugs and missing features... I forgot to tell them how much I love the platform and the great work they do but I am sure they know that ;-)

For the next two timeslots I was not attending a session as I supported the self-paced hands on labs (part of the price you pay for getting admitted free as an MVP... small price if you ask me :-)

After that I attended an interesting session in an area I have no experience and, if I am honest, no immediate interest: "Game Development Using Managed Direct3D Mobile with the .NET Compact Framework"

Finally, one of the highlights of the day was "Memory Architecture in the .NET Compact Framework". I was looking forward to this session and I certainly was not disappointed. Fantastic info!

Then I hung around at the "Ask the Experts" session while consuming food and alcohol... at the same time the Exhibition opened so it was time to collect all the freebies...

The day ended with a screening of the code room... very funny :-D

Of course, the most beneficial aspect is the impromptu conversations held with various MSFT and MVP guys (and girls)... There are some real smart people here!

Due to some weird alcohol spillage that I will not go into, I cannot get photos from my camera onto this laptop and it is too late here so I'll be looking into it tomorrow... there will be photos tomorrow I promise!


Tue, May 10, 2005, 12:08 AM under dotNET
Can you think about the amount of information that is part of your knowledge and account for it in terms of where you found out and how you consider it as common knowledge? Well, it turns out there is some stuff in my head that I thought everyone knew but it is not true. So I might as well capture it here on my blog.

What does mscorlib stand for? Stop reading! Don’t look for the answer, just try and work out the answer. What does the main dll of .the NET Framework stand for? What was the codename or first candidate name if you like, for C#? Well here are my answers (this is just my understanding which I cannot track back to a reference!):

C# and the design of this new .NET language ws COOL! More importantly, mscorlib has 3 parts to its name: ms cor lib.
ms: Magnificent Software (ok, it is Microsoft :-)
lib: as you expect this means library
cor: Before .NET was chosen as the name, this new platform was a successor to COM so it was codenamed COM 3.0 and then the name chosen was… Common Object Runtime (cor) and that is where mscorlib derives its name from (and that stuck regardless of the fact that .NET was the final name)!

So, now you know ;-) And if you knew already now you have something to point to!

MEDC registration

Mon, May 9, 2005, 03:32 PM under Events
Although I have had two nights here in Vegas, today (Monday) is almost the first day of MEDC. There are the two pre-conference tutorials (which I am not attending), communications network (which I don't neeed so far as I have wireless internet access here at the hotel ;-) and registration.

Check out the photos of a couple of signs I followed through the vast Mandalay Bay to find registration. I then received my badge and bag.

Contents of the bag include guide, conference evaluation form, the May edition of PocketPC magasine, A4 notepad, travel mug, half a dozen 3rd party flyers and the following disc packs: Mobile Application Development Toolkit, Windows Embedded Introductory Kit, and evaluation versions of Windows XP Embedded SP2 & Windows CE 5.0.

Since the bag's "convenient side entry computer compartment" is not large enough for my Dell Precision M60, I'll be going round with my bright yellow TechEd 2001 bag. If that is not enough to make me stand out, I am also carrying a limp after straining my right ankle yesterday :-(

More later...

Blog link of the week 18

Sun, May 8, 2005, 05:13 PM under Links
James gives some insight to what it's like preparing MEDC.

David and Scott inform us of their sessions (both of them in my top 3 choices) and provide interesting links.

OT: I just came back from a trip to the Grand Canyon and I'll tell you the obvious: it is massive and as they say round here...awesome! No picture or video can capture it but I'll have photos soon at the usual place.

Leaving for Las Vegas

Fri, May 6, 2005, 09:33 PM under Personal
Leaving in half an hour for the airport to fly to Vegas for MEDC. Back in a week.

Unless something goes horribly wrong, I will be blogging throughout the conference reporting my views, photos or whatever.

Stay tuned!

PS If you are going to be there and wish to hook up and talk geek, this is what I look like:

1. Taken a decade ago but not far from the truth
2. Dancing under the sun in Ios
3. Playing chess
4. Favourite non-tech past time

Attributes in properties of code file

Fri, May 6, 2005, 10:57 AM under Whidbey | VisualStudio
The more I use VS2005 Beta 2 the more I come across (little) new things.

Make sure you have the properties window open/docked (you know, the one where you usually change the properties of controls).

Open a code file (i.e. a class) and place the cursor on the class declaration. Look in the properties window. You can toggle the 3 boolean combobox options to insert/remove the 3 corresponding attributes: COM Class, COM Visible and Serializable.

This appears to be a VB thing only. It's been a while since I said that in a positive way :-)

Now, would the VSD (Visual Studio for Devices) team please remove the Serializable option, as it does not apply to CF?


Fri, May 6, 2005, 12:19 AM under MobileAndEmbedded
All Compact Framework developers know that without pinvoking you cannot author any serious CF 1.0 application.

We've all been in the situation where we have declared a function from coredll.dll (or some other native dll) and when we called it we got the infamous MissingMethodException (meaning the DllImport declaration was wrong). That is the only way to find out, try it and see.

Well, CF 2.0 gets support for a method that is already in there in the full desktop .net framework version 1.1. The method in question is Marshal.PreLink/PreLinkAll. It basically verifies that your dllimports have been declared properly, e.g.
static void Main() {
// Assuming all your dllimports are in Form1
Application.Run(new Form1());

My suggestion is to still test the methods explicitly from your code, but I will be using this shortcut when in debug mode; it's a sweet little time saver :-)

SuppressMessage not in CF

Thu, May 5, 2005, 01:52 PM under MobileAndEmbedded
As you may have noticed, in VS2005 you can turn static code analysis on via the project properties ("Enable Code Analysis"). Many of the rules are just guidelines and do not qualify as warnings. There should be a separate category, maybe called *recommendations*. However, that is not the point of this blog post.

Fortunately, you can suppress warnings simply by right clicking on them and choosing "Suppress". What that does is to add an attribute to the line of code that breaks the recommendation so next time you compile/build, the annoying warning will not appear in the error list. The attribute is the System.Diagnostics.CodeAnalysis.SuppressMessageAttribute (it applies only if the compilation constant CODE_ANALYSIS is defined)

// no comments on the content of the method please
public void SomeMethod(bool b, object o) {
if (b) {
((EventHandler)o).Invoke(null, EventArgs.Empty);
} else {
((EventHandler)o).BeginInvoke(null, EventArgs.Empty, null, null);
One of the 4 warnings you'll see for the method above is the following:
CA1800 : Microsoft.Performance : 'o', a parameter, is cast to type 'System.EventHandler' multiple times in method Class1.SomeMethod(Boolean, Object):Void. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant castclass instruction.

So, you bring up the contextmenu for the item in the "Error List", select "Suppress message" and life is good again.

So where is the problem? As the title of this entry suggests, the attribute is not supported by the Compact Framework (at least in Beta 2) and doesn't compile:
The type or namespace name 'CodeAnalysis' does not exist in the namespace 'System.Diagnostics' (are you missing an assembly reference?)

There are two issues with that:
1. You cannot suppress those annoying recommendations warnings that shouldn't be there in the first place.
2. If you are sharing code between the full and compact frameworks, you'll get compilation errors.

There is nothing you can do about the 1st one (apart from vote for it).
For the second, as you know, you can use conditional compilation. However, in this case I'd go ahead and define the attribute in code in your CF projects, so at least you get past the compilation problem. Define it like this:
namespace System.Diagnostics.CodeAnalysis {
public class SuppressMessageAttribute : Attribute {
public SuppressMessageAttribute(string category, string checkId) {}

Note, I tried implementing the attribute fully but the warnings were still not suppressed so the bare minimum skeleton as above is good enough to at least get us past the compilation errors

CLSCompliant now works

Tue, May 3, 2005, 02:02 PM under Whidbey | VisualStudio
VB Class Library projects are marked at the assembly level with CLSCompliant (while in C# you have to add it yourself). The most important reason for turning it on in your C# library projects is so that you don't accidentally expose case sensitive *publics*; not only this is not CLS compliant, but it would render your assembly unusable by VB code.

So, while it is bizarre that the option is not turned on for C# by default and it is for VB, it makes no difference because it has no effect for VB projects! The situation changes with Whidbey, where suddenly it works as expected. I guess it got noticed when VB got support for unsigned types (also not CLS compliant).

How did I find out? Some of my assemblies are exposed to VB6 clients, so I have public interfaces starting with an underscore (representing the default interface) and other starting with double underscore (representing the default events interface). When I upgraded them to VS2005 B2, I got a whole bunch of CLS compliancy errors (no public types may start with _). BTW, my solution was to mark them as CLSCompliant(false) rather than tweak the public interfaces and then have to modify all clients too.

FYI, with Whidbey, the C# team persists with their choice of not marking the C# projects with the CLSCompliant attribute by default... is that arrogance?

Synchronize Class View

Mon, May 2, 2005, 11:59 AM under Whidbey | VisualStudio
When in the code editor of Visual Studio, one of the items I use most on the context menu is the "Synchronize Class View" menu item. As you expect/know, it activates the "Class View" docked window, expanding the tree nodes as appropriate and selecting the item which you have the cursor on in the code. I love this feature, and my jaw dropped when I couldn't find it on the VS2005 context menu!

I quickly went through the top level menus and their children trying to find where this option lives; no joy. Since every action in VS has a keyboard shortcut, I thought I'd go to the Tools->Options->Environment->Keyboard and see if I can find it that way. Lo and behold, it appears as the 5th item in the auto-filtered list as soon as I type "Sync": View.SynchronizeClassView. I cancel the Options dialog with a smile :-)

Armed with this knowledge (i.e. that the option lives under View), I can add the option to the context menu. Here are the steps, if you wish to do the same:
1. Select Tools->Customize
2. On the Toolbars tab, check the "Shortcut Menus" item
3. Observe how 6 drop down menus appear on the toolbar, the first one being "Editor Shortcut Menus"
4. Still in the Customize dialog, select the "Commands" tab, select "View" on the left and locate on the right the "Synchronize Class View" item.
5. You can now drag the item to the "Editor Shortcut Menus" and drop it wherever you want (I placed it on top of "Go to Definition")
6. Close

Editor life is back to normal again...

Blog link of the week 17

Sun, May 1, 2005, 03:28 PM under Links
* The debate that never ends: VB vs C#

* Message to the VB team: Remove the crutches (why do I think that falls on deaf ears?)

* "Hello world" with code coverage

* I didn't know that either! I'll have to revisit those remoting projects, where I needed to debug server and client at the same time!