Craig's .NET Cautions
Be Careful when Upgrading
VB.NET includes an upgrade wizard that will move your VB6 projects to VS.NET. First, it will only upgrade VB6 projects; if you still have VB5 or lower, you'll have to upgrade those to VB6, and then to VB.NET. However, one key piece of information is to make sure the VB6 project properly compiles and runs on the machine on which you will be doing the upgrade. If your VB6 project relies on certain components that are not installed on the machine performing the upgrade, there is no way for the upgrade to work. Therefore, compile your VB6 application on the machine performing the upgrade first; only if it compiles and runs should you then try to upgrade it.
Don't Go Inheritance Crazy
VB.NET is truly object-oriented; for the first time, you have true inheritance. While inheritance is very powerful, and has been requested by VB developers for years, it doesn't always make sense. One thing you don't want to do is include inheritance everywhere just because it's cool. Inheritance is best used when one class needs the same basic functionality as another class. If you have classes that may have the same basic structure, but will have little or none of the same functionality, consider using interfaces instead of inheritance.
Look Closely at your use of APIs
There's nothing wrong with the use of the Windows API, but you should know that they don't typically upgrade well from VB6 to VB.NET. More importantly, many of the reasons people use the Windows API are to do things you couldn't do in VB. Now, most of those items are provided to you by the .NET Framework. If you need free threading, you now have that in the Framework, so there's no need to call the Windows API in order to create new threads.
Be Aware: Deterministic Finalization is Gone
In VB6, when you set an object to nothing, it dropped out of memory. In VB.NET, when you set an object to nothing, the reference drops, but the object does not necessarily disappear immediately. In .NET, the Framework provides garbage collection for you. The garbage collector destroys objects that are marked for collection (objects that have no one referencing them). The thread on which the garbage collector runs may not come by for several seconds, if the system is quite busy. This means that you cannot determine, with certainty, when the object is destroyed. It will be destroyed, but you don't know when. While this seems like you might be losing some control, the garbage collector can destroy objects that only have circular references to each other, helping clear up one of the bugs often associated with object use.