Threading in .NET

If you have some trouble in updating GUI elements in .NET because they are not created by the thread just running, try the following:

delegate void onSensorChangeParameterDelegate(int index, int sensorValue);
void kit_OnSensorChange(int index, int sensorValue)
{
    if (InvokeRequired)
    {
        BeginInvoke(new onSensorChangeParameterDelegate(kit_OnSensorChange), new object[] { index, sensorValue });
        return;
    }
    txtInfo.Text = String.Format("Index={0}, Value={1}", index, sensorValue);
}

 

So the method is handed over to the GUI thread, where txtInfo is a TextField, and processed there. Jon has written a great article about threading in .NET and how it can be done.

Visual Studio 2005 Highlighting Feature

Have you realized already this great feature in Visual Studio 2005?

Visual Studio Highlighting

If you write down some interface or class names which do not exist yet, they appear in black (as long as you still use the default settings for the editor). As soon as you write down the appropriate class or interface the color changes from black to light blue. Why this is cool? It makes it pretty easy to find typos in your code right before compiling. If you see such code not in the appropriate color, either you have a typo in its name or the class or the interface is not implemented yet. It makes a lot of sense when you write down code but the implementation of a class or interface is not yet available because it is written by another person. It’s a nice feature in VS 2005.

Implement Interface

If you have to use often contracts in Microsoft Communication Foundatation aka Indigo, sometimes you become really bored by implementing all the interfaces. Visual Studio 2005 helps you saving a lot of time by choosing the interface your class inherits from. Using the Implement Interface menu item you will get all the methods required by the interface.

Implement Interface

P/Invoke Data Type Matching

Creating this table took a while, but saved me hours…

Windows Data Type .NET Data Type
BOOL, BOOLEAN Boolean or Int32
BSTR String
BYTE Byte
CHAR Char
DOUBLE Double
DWORD Int32 or UInt32
FLOAT Single
HANDLE IntPtr, UintPtr or HandleRef
HRESULT Int32 or UInt32
INT Int32
LANGID Int16 or UInt16
LCID Int32 or UInt32
LONG Int32
LPARAM IntPtr, UintPtr or Object
LPCSTR String
LPCTSTR String
LPCWSTR String
LPSTR String or StringBuilder*
LPTSTR String or StringBuilder
LPWSTR String or StringBuilder
LPVOID IntPtr, UintPtr or Object
LRESULT IntPtr
SAFEARRAY .NET array type
SHORT Int16
TCHAR Char
UCHAR SByte
UINT Int32 or UInt32
ULONG Int32 or UInt32
VARIANT Object
VARIANT_BOOL Boolean
WCHAR Char
WORD Int16 or UInt16
WPARAM IntPtr, UintPtr or Object

Standard Numeric Format Strings

It usually takes ages until I find the page with the format strings on MSDN. So here’s a short overview:

C or c = Currency
D or d = Decimal
E or e = Scientific (exponential)
F or f = Fixed-point
G or g = General
N or n = Number
P or p =  Percent
R or r = Round-trip
X or x = Hexadecimal

NUnit .NET 2.0 compliant

The current iteration release of NUnit 2.2.2 should work fine with assemblies build in Visual Studio .NET 2005. Nevertheless some problems occur after installing Visual Studio .NET 2005 Beta 2. Check out the installation folder of NUnit, usually C:\Program Files\NUnit 2.2.2\bin. Here you should modify the file nunit-gui.exe.config.

<startup>
  <supportedRuntime version="v2.0.50215" />
  <supportedRuntime version="v1.1.4322" />
  <supportedRuntime version="v1.0.3705" />
  <requiredRuntime version="v1.0.3705" />
</startup>

The version of .NET 2.0 on your system is slightly different due to the installation of Visual Studio .NET Beta 2.

WaitOne and PInvoke

Unfortunately, there is no way to copy a .NET desktop application to a compact framework based system. The compact framework does only support a subset of the .NET library.

Two typical problems while migrating a multi-threaded application to the Compact Framework can be solved as following:

The first issue appears when using the Sleep-method of threads.

System.TimeSpan yield = new System.TimeSpan(10);
System.Threading.Thread.Sleep(yield);

The compact framework does not support any signature accepting TimeSpan as parameter. Simply convert the value to an integer using the milliseconds solves this one.

System.TimeSpan ts = new System.TimeSpan(10);
int yield = ts.Milliseconds;
System.Threading.Thread.Sleep(yield);

More complex is the usage of the WaitOne-method. WaitOne only provides a signature without any parameters on the compact Ffamework. A simple solution is the usage of the following PInvoke

[System.Runtime.InteropServices.DllImport("CoreDll.dll")]
private extern static Int32 WaitForSingleObject(System.IntPtr Handle,System.Int32 Wait);

Using this you can substitute calls similar to this

foo.WaitOne((int)((bar - System.DateTime.Now.Ticks), false);

by the flowing lines to achieve the same result:

System.IntPtr hProcess = foo.Handle;
System.Int32 wait = (int)((bar - System.DateTime.Now.Ticks));
WaitForSingleObject(hProcess, wait);