Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, March 25, 2008

Flashing and Flickering


Since its creating a couple years ago, our C# charting product has had an issue with flashing and flickering. Several of us have tried several different ways to enable double buffering. This seemed like the solution, especially drawing from our experience in Java. But no matter how we set it, nothing ever changed. So I figured we must just be calling some Paint() method somewhere too many times. I dug through our source again with a debugger trying to figure things out. On occasion, Paint() methods were being called twice, but this didn't seem to correlate with flashing at all. And it was probably part of the setup as well to make sure things appeared correctly.

I then embarked on another search of the Internet trying to find out how to really enable double buffering in .NET. I stumbled upon an answer that was slightly different than anything I've tried before. Specifically, I've always been trying to use various versions of

this.SetStyle(ControlStyles.DoubleBuffer, true);

in various different places. There seemed to be a lot of potential places due to the object hierarchy we have in place. But the latest suggestion I found this morning was to set

this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);

and set all those bits on the Control object in its constructor. Well, this was new to me and actually points to one specific object in the package - the Panel that holds the Charts. I added this line to each of its constructors, rebuilt the package and ran our tests. Everything not only passed, but there was no more flashing! Then I ran our demo gallery (a set of examples and much more demanding than the simple tests) and everything looked great!

So thank you to random forum poster somewhere!

Tuesday, November 7, 2006

Fatal Error CS0009

fatal error CS0009: Metadata file 'c:\Documents and Settings\ed\My Documents\VNI\conferences\SC06\tasks\ImslCS.dll' could not be opened -- 'There isn't metadata in the memory or stream'
I got this error for what I think is a known reason. We're actively working to support both .NET 1.1 and .NET 2.0 with IMSL C#, and it's proven to be quite a challenge. Many of our Acceptance Tests (ATs) failed under 2.0 because Microsoft decided to change the way they deal with double values. Anyway, we've got various working DLLs now and are moving onto a question of needing both 64-bit and 32-bit DLLs for .NET 2.0.
As part of this test, I took a 64-bit .NET 2.0 DLL and dropped it onto my system running 32-bit Windows XP and tried to build a very simple example. The error I got is what's quoted above. Reading around on the Internet, I see lots of people running into this because they're using COM DLLs rather than .NET Assemblies. And the MSDN Page is less than helpful. So while you may see this because you don't have a .NET assembly, you might also see this when you know you've got one. But now you need to find out if it's an assembly built with /platform:x64 while you're running on /platform:x86.

Friday, August 25, 2006

Serialization in .NET

I had a Java example to work from, but had to do this in .NET. In this case, my class basically had a Hashtable that I wanted to serialize. On the Java side, there really isn't much more to this than creating an ObjectOutputStream and then calling writeObject(this). If you add implements Serializable and add a couple UIDs, you're all set. Actually very easy.

Well, not so much on the C# side. First, you class needs to have the [Serializable()] attribute set and you also implement ISerializable. All fine so far, but implementing this interface means you need a GetObjectData method too. Visual Studio drops the skeleton in your class, but that's were my general clue of what I was doing stopped.

Instead of going through all the crap I went through, in the end you need to simply add a couple lines in GetObjectData to add whatever local variables you want to serialize. In this case, it was just that Hashtable, so my method looks like:
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("hashSeries", hashSeries);
}

So that's all and fine -- but you need to realize now that you've only got a way to get the data serialized. The part they don't really tell you is that now you need a special ctor for your serializable class that's used when you call Deserialize on the input stream and cast it back to your original object. This constructor needs the same parameters as that GetObjectData method and basically just does things in reverse:
protected StockDatabase(SerializationInfo info, StreamingContext context)
{
hashSeries = (Hashtable)info.GetValue("hashSeries", typeof(Hashtable));
}
Simple as pie right? I really didn't spin my wheels too long on this one, but I did do some real research trying to find a good example and piece together the bits from the various things I saw on the way to something that works. The best example ended up being the one for the Deserialize Method even though it doesn't serialize a class object.

Friday, August 11, 2006

.Not

Writing a lot of C# code lately. While you really appreciate Visual Studio quickly, there's some things about .NET that aren't that fun to learn. An interesting page on what's bad about .NET in general: .Not, the .Net hall of shame. Delegates and event handling are another odd can of worms. Maybe it makes sense if you know C++ (I don't), but to a Java hack, it takes some getting used to. And if you're coming from Java, Microsoft of course wants you to drink their Kool-aid: C# for Java Developer.