Friday, March 24, 2006

A Welcoming Breaking-Change in .Net Framework 2.0

Finally, after a few years waiting, Microsoft admits its implementation of DateTime serialization in web service is flawed, and made a breaking change to it. See the last item on this page: http://msdn.microsoft.com/netframework/programming/breakingchanges/runtime/xmlserial.aspx

In one sentence, under the old framework, only local time can be transmitted correctly by web service. If you save UTC time in database, and try to transmit using web service, bad luck. You will have to convert all the time in to your web server's local time, then send it out. And, on the other end, the receiving computer will have to convert again the date time to UTC time. And, under the hood the web server and receiving computer both did some conversion during XML serialization and de-serialization too. That is about 4 times CPU time wasted on the conversion that leads you back to where you started!!! Even worse, this behavior is not well documented in MSDN, and causes big confusion for developers.

I had to send an internal memo to all developers in my company to raise the awarness of this issue back in 2004. Really glad it finally gets attention and being resolved.

srand() and threads in MFC

This is an old problem I only run into recently: You should call srand() for each and every thread that calls rand().

In its multi-thread version, the CRT implemenation in VC++6.0 will save seed to thread local storage. So, it is necessary to seed the rand() function in every new thread your program created. Otherwise, the random number sequence is same as if seeded by 1. This poses 2 serious questions:
  1. How can I write a class that is thread safe, and caller won't have to worry about calling srand() whenever they create a new thread? I do not have a solution yet. The best I can think of is to ask callers, when not sure, always call srand() whenever a new thread is created;
  2. A second question is what if user creates multiple threads in a batch, this will make the recommended intialization code: srand( (unsigned) time(NULL)); fail, because the threads are created within 1 second, and you will get the same sequence in all your threads. After some searching, I found this discussion thread to be quite helpful: It proposed to multiply time by the thread ID to seed rand().

Using Transition Channel in Macromedia Director

I tried the transition channel in Macromedia Director MX 2004 recently. It
turns out to be quite tricky to use it correctly. At first, I just double clicked
in the score and selected a transition effect. And it works immediately. What
a relief, it is as easy as PowerPoint. Soon, I realized that I was wrong.

The first problems showed up after I tried to add some Lingo scripts to the
frame with transition effect.

First, I want the movie to loop on the frame until user clicks some
button. I find that the movie becomes extremely slow on this frame, and the movie takes about
50% CPU time. Then, in the "Using Director" online help, I found this
warning:
  • Avoid looping on a frame that contains a transition. Playing a transition continuously
    might cause performance issues.
So, I have made a well-documented mistake here. That is the first
tricky issue I have with transition channel.

However, it took me longer than it should be to fingure out the above problem, because
I used the "Dissolve Patterns" transition effect. It won't show any visual changes
when I am looping the frame, although it still takes 50% CPU time to calculate
the transition effect. This fooled me into believing it only did the transition
once and stopped, and was not suspecious of the transition being the source
of performance problem on that frame. If I had used the "Cover Up"
transition, I should have seen the screen repeatedly rolling up, and discover
the problem in the first test run.

The second issue appears when I am trying to add a sprite to show me the current
frame number. I first added a text
member to the lower left corner of the stage like this:



Then I added this behavior to the
sprite:

on prepareFrame me
frameString = "" && _movie.frame
if(frameString <> member("FrameNumber").text) then
member("FrameNumber").text = frameString
end if
end

Again, the transition stopped working, the screen just freeze for 2 seconds (the default
duration used by the transition) then move on. I have not found any document
about this problem yet. But, my investigation showed that the offending code
is the highlighted line above. If I run the same code in enterFrame event handler, it won't be a problem. Or if I remove the line from prepareFrame handler, the transition will showup normally. I am not sure why is this a problem. For now, I will just avoid doing anything like this on a transition frame.

The lessons:

  1. Never loop on a frame that contains a transition;

  2. Do not change a text member's text property in "prepareFrame"
    event of the transition frame (there may be a more general description about this problem);