Silverlight aka WPF/E

April 24, 2007

It seems Microsoft has at last christened WPF/E Silverlight and acknowledged it’s a Flash and Flex beater (contender)!

Advertisements

Having just had another article published on codeproject, I am reminded yet again how much I miss many of the features of C++ when I’m coding in C#. There’s no denying C# is a very productive language, but C++ techniques I have used and taken for granted just aren’t possible.Generics are a case in point. I constantly feel C# is wanting to hold my hand while crossing the programming road. Generics and C++ templates are not the same thing – the design goals are very different. C# generics are like classes that have a type parameter and everything (pretty much) happens at runtime and C++ templates are just macros that look like classes and it all comes together at compile (and maybe link) time.

If all you do with templates is type safe collections, this is probably not an issue and generics could be considered a safer approach, but it is very limiting. In the SyncInvoker article I use template metaprogramming to achieve code reusability. More accurately I guess this comes under the heading of generic programming so I avoid having the re-write sections of similar code that have minor variations. I guess I’m just lazy.

Template metaprogramming allows the programmer to concentrate on architecture and delegate to the compiler the generation of any implementation required by client code. With template metaprogramming you can create truly generic code – a smaller codebase and better maintainability. However, the syntax and idioms of template metaprogramming are esoteric compared to conventional C++ programming sometimes even the most trivial, template metaprogramming can be very difficult to understand.

Tangosol (aka Oracle) has a .NET version of Coherence that’s been available for a few months now. Previously, it was possible to use Coherence in a .NET or unmanaged C++ project, but required the use of a thirdparty or home grown JNI proxy mechanism – maybe Codemesh. However, Coherence.NET provides a native .NET serialization mechanism which makes it’s use in a C# GUI pretty straightforward.

Which ever objects you want to work with the cache simply need to ne derived from IPortableObject , add some getters and setters and implement the ReadExternal and WriteExternal methods. This example is lifted straight out of Tangosol sample code.


public class ContactInfo : IPortableObject
{
private string name;
private string street;
private string city;
private string state;
private string zip;
public ContactInfo()
{ }

public ContactInfo(string name, string street, string city, string state, string zip)
{
Name = name;
Street = street;
City = city;
State = state;
Zip = zip;
}

public override int GetHashCode()
{
return name == null ? 0 : name.GetHashCode();
}

public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}

ContactInfo contactInfo = obj as ContactInfo;
return contactInfo != null &&
Equals(Name, contactInfo.Name) &&
Equals(Street, contactInfo.Street) &&
Equals(City, contactInfo.City) &&
Equals(State, contactInfo.State) &&
Equals(Zip, contactInfo.Zip);
}

public override string ToString()
{
return "ContactInfo("
+ "Name=" + Name
+ ", Street=" + Street
+ ", City=" + City
+ ", State=" + State
+ ", Zip=" + Zip
+ ')';
}

public void ReadExternal(IPofReader reader)
{
Name = reader.ReadString(0);
Street = reader.ReadString(1);
City = reader.ReadString(2);
State = reader.ReadString(3);
Zip = reader.ReadString(4);
}

public void WriteExternal(IPofWriter writer)
{
writer.WriteString(0, Name);
writer.WriteString(1, Street);
writer.WriteString(2, City);
writer.WriteString(3, State);
writer.WriteString(4, Zip);
}
}

Thoughtfully, they have also provided a couple of apparently useful classes to make the GUI developers life easy. WindowsFormsCacheListener and CacheEventHandler classes are there so the GUI develeoper doesn't have to worry about which thread the cache events are raised on and the associated GUI thread update problem.

public partial class ContactInfoForm : Form
{
  ...
  listener = new WindowsFormsCacheListener(this);
  listener.EntryInserted += new CacheEventHandler(AddRow);
  listener.EntryInserted += new CacheEventHandler(AddAnotherRow);
  listener.EntryUpdated += new CacheEventHandler(UpdateRow);
  listener.EntryDeleted += new CacheEventHandler(DeleteRow);
  ...
  cache.AddCacheListener(listener);
  ...
}
private void AddRow(object sender, CacheEventArgs args)
{
 throw new Exception();
}
private void AddAnotherRow(object sender, CacheEventArgs args)
{
...
}
private void UpdateRow(object sender, CacheEventArgs args)
{
...
}
private void DeleteRow(object sender, CacheEventArgs args)
{
...
}

I’m always wary of this style of coding in C#. Is it truely thread safe and what happens when exceptions are thrown – all the classic multicast delegate and event issues. A simple change to the above code to add another EntryInserted delegate gives us the answer (I added the AddAnotherRow and the hard thrown exception). As expected, the exception means the subsequent delegates aren’t called and it fails silently. For any GUI design in a fast moving financial environment, this is a real problem.

It also leads me to wonder if another thread comes along and and removes the delegate from the CacheEventHandler mid call what happens. I’ve blogged about this before (who hasn’t?). This a very easy trap to fall into when using delegates and events in a multithreaded C# GUI application.