Refresh

I was with the Windows 7 RC yesterday and noticed something really cool. I was watching a video on Hulu (using the web client) and as the mouse hovered over the Internet Explorer icon in the taskbar, I noticed the thumbnail view of the page was a live rendering, showing the video playing in real-time. It’s perhaps not terribly useful but it is pretty cool and a testament to what can be achieved on modern hardware.

Thinking along the lines of powerful hardware and immediate feedback and representation, I was, unfortunately, struck with this disappointing bit,

windows 7 folder refresh

The folder refresh option in the context menu. It’s somewhat sad that this still exists and updated data from the file system isn’t polled, updated, and displayed automatically by the OS. (There may very well be valid reasons for not doing this [e.g. cost due to hard disk seek + latency] but it’s disappointing none the less.)

I also bring this up because it was something that came to mind in the design of Fragment Sync. If you used an early version of FS, you might have noticed a refresh link in the Setup window; you would click it and it would updated the list of devices to show/update which ones were active or inactive. I reached the conclusion early on that this was horribly annoying and it would cost next to nothing to automatically detect and display such information, and at this juncture I conjured up a rule that there should be no “refresh” buttons, links, or whatever else in Fragment Sync, and all state changes should be detected and addressed automatically, without user intervention.


Miscellaneous Mono and Mono WinForms issues

A few issues I stumbled across as I was working on porting Fragment Sync,

Issue #1: Explicit null second argument with ArrayList.BinarySearch
The second argument is optional and leaving it out should (I assume) be the same as passing null resulting in the method using the object’s CompareTo() method (implemented b/c of required IComparable interface). However, Mono threw an exception: System.ArgumentException : Comparer threw an exception

Issue #2: LinkLabel rendering issues
You can see this in the screenshot from my previous post,

mono winforms linklabel rendering issue

The linklabels at the bottom have their AutoSize properties set to false and their TextAlign properties set to MiddleCenter; the rendering issue is obvious (oddly enough, I noticed when a linklabel is disabled it renders correctly). Setting AutoSize to true and redoing some positioning, I got the following (note that a lot of other things have been fixed here as well focus on the menu at the bottom),

mono winforms linklabel rendering issue 2

I’m still working on this and haven’t really found an optimal or pragmatic solution as yet.

Issue #3: No WYSIWYG for improperly anchored controls
Microsoft .Net Framework seems to be able to display a form as-is despite any sort of improper anchoring which would cause issues when resizing. Mono WinForms seems to behave a bit differently, and the position and layout of these controls are not identical to how they look in the designer. My guess would be that form are loaded differently between the 2 implementations.

Issue #4: Panel anchor issue
In Fragment Sync, there is a panel just above the bottom menu that appears and displays notifications. This panel is anchored to stay just above the bottom menu. For reasons I still haven’t figured out, this panel disappeared (I assumed behind the menu). I fought with this for quite a while, but finally surrendered and simply docked it to the bottom. I’m still not sure exactly what the issue was here and anchoring and docking seems to work fine in other forms and controls.

Issue #5: AutoScaleMode
This is something I never payed attention to, but the Visual Studio designer automatically sets AutoScaleMode to AutoScaleMode.Font for every form or user control created. This can very much screw up positioning and layout of elements, so I set it to AutoScaleMode.None for everything. Fragment Sync doesn’t really concern itself with scaling, so this might not be appropriate for every app. Not that this should be done within the designer, trying to change it after InitializeComponent() is called in the constructor seems to have no effect.

Issue #6: Form icon issue
I mentioned in the previous post about problem with Vista-compatible icons which have an embedded 256×256 png. Rather than muck around in the form designer code this can be addressed in the form constructor after the InitializeComponent() call, as the exception for the problematic icon is thrown when the form is shown not initialized. So simply set this.Icon = null; after InitializeComponent() or set this.Icon to a compatible icon.

Issue #7: Notify icon issue
This is caused by the same problem as above (Vista-compatible icons), but can’t be addressed after InitializeComponent() as the exception is thrown earlier, within InitializeComponent(). The easiest fix to just use another icon with the 256×256 bitmaps removed. You could also muck around in the form designer code and edit the offending line.

That’s it for now. I’m eager to do a OS X compile and run, which I’ll try to do within the week.


First thoughts on porting to Mono

I’ve known about Mono since its inception, but a few months ago I really became interested as support for C# 2.0 and WinForms 2.0 was announced. I played around with some code and was pretty impressed at how easy it was to get stuff compiled and running. This weekend I made a concerted effort to tackle something more complex, getting Fragment Sync compiled and running. I’ve read you can simply use Mono with the managed executable and not have to deal with compiling source code, but Fragment Sync does quite a bit of interop with unmanaged code so that really wasn’t an option.

I first attempted to import all the source files into MonoDevelop (commenting out win32 specific stuff), but this proved problematic when it came to resources. I tried a ton of different things, but could not get MonoDevelop to properly compile in the app’s resources. I then read you can just open the Visual Studio solution with MonoDevelop; this proved to be effortless and resolved the compilation issue with resources.

After a successful compiled, I had some issues getting a window up. There was an issue loading the application icon. This seems to be an issue with using Vista-compatible icons (where the 256×256 sized bitmap, is an embedded png). I changed the icon to null for a few forms to resolve this; which involves the following line in the form designer code:

this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));

The final and most serious issue I encountered was with Fragment Sync’s Rijndael encryption code. You can find the issue described in detail here. Note the issue will pop up when using CryptoStream as well, since CryptoStream simply abstracts the calls to the underlying Transform methods of ICryptoTransform. The trick here is to always check that you can reuse the transform. With Microsoft’s implementation you can, with Mono you can’t. So you have to recreate the transform object.

if (!decryptor.CanReuseTransform)
{
    decryptor = rij.CreateDecryptor();
}

With these issues resolved I could get things up and running.

fragment sync running on mono in opensuse

Obviously things don’t look pretty, but I think this is a good starting point to work from to get Linux support for Fragment Sync.

I should mention I did consider using Gtk# and redoing the Fragment Sync user interfaces, but I found Gtk’s design methodology unbearable… let’s just say I’m not a fan of packing widgets into containers.


Updates to fragmentsync.com and upcoming Amazon S3 support

Some minor aesthetic updates to the fragmentsync.com front page:

fragmentsync.com screenshot

Also, as the twitter feed says, Amazon S3 support is coming. I just started using S3 and so far I’m very impressed with the speed and performance. I should also give a shout-out to LitS3, which is an excellent C# library for S3 access and is the backbone for S3 operations in Fragment Sync.


Fragment Sync box shot

I came across ConnectCode Software Box Shot Maker on CodeGuru, meant as a demo of C# and Windows Presentation Foundation. It’s a pretty cool app, and I played around with it for a few minutes and did a box shot of Fragment Sync.

fragment sync box shot

Anti-aliasing would have been nice, but I did a quick bit of supersampling by reducing the original screenshot by half.


More .Net FtpWebRequest woes

This time it’s an issue with the SIZE command. As explained here,

Some servers require sending “TYPE I” before the SIZE command will work.

Note that setting FtpWebRequest.UseBinary to true (which it is by default) does not correct this. When getting the response, an exception will be thrown telling you the file is unavailable and you’ll get a 550 error with the message, “SIZE not allowed in ASCII mode”.

A discussion and Microsoft’s response to this issue is available here; it pretty much boils down to tough noogies, it’ll be fixed in a future version.


.Net FtpWebRequest and 503 (bad sequence of commands) errors

I’ve been working on some FTP code in C# with the .Net framework’s FTP classes and frustrated that I was occasionally getting 503 (bad sequence of commands) errors. Turns out these errors will pop up if the FtpWebRequest.KeepAlive property is set to true, which it is by default. Unfortunately, this doesn’t really address why this is occurring in the first place. I’m doing a lot of multithreaded stuff, so perhaps that’s the culprit (i.e. 2+ threads using the same connection, layering their calls on top of each other). However, I’ve found some forum posts (such as this one) indicating others are having the same issue doing seemingly serial, non-asynchronous stuff.


DPC latency issues

Last month the motherboard in my main desktop died. I replaced it with this board (GA-MA78G-DS3HP) from Gigabyte (I had some reservations, as the previous board was from Gigabyte as well, but the price and feature-set won me over). The installation went smoothly and I was surprised that Windows booted up (probably b/c of similarities due to both boards coming from the same manufacturer; fyi, I later discovered there is a way to install a new motherboard w/o a windows reinstall). I was pretty happy until I started hearing seemingly random stuttering in the audio. It was very short, but noticeable, especially in games.

I spend hours trying to figure this out. I was thinking it was the onboard sound, but it was Realtek audio, which I’ve never had issues with, and this new board has one of their best chipsets. I finally stumbled across some forum posts mentioning DPC latency and the DPC Latency Checker. I had no clue what DPC latency was, but it’s summed up nicely on DPC Latency Checker page,

If any kernel-mode device driver in your Windows system is implemented improperly and causes excessive latencies of Deferred Procedure Calls (DPCs) then probably drop-outs will occur when you use real-time audio or video streaming applications.

This is a wonderful utility, and, sure enough, after a few tests I noticed very long red bars, indicating I indeed had a DPC latency issue. Now, there are issues with older Gigabyte boards and DPC latency issues, discussed in this Anandtech thread, but the board I purchased was newer that those afflicted. What was also curious was how the issue was occurring. I was not getting steady red bars, but spikes, and after many hours of pulling my hair out, I finally realized that that the spikes were coming from the keyboard and they were fairly random in occurrence (although more prevalent within Direct3d or OpenGL games and apps).

Trying to think of solutions and trying to avoid a BIOS update, I tried a repair install of Windows; perhaps something went wrong b/c I was using a new motherboard w/o a clean installation. The repair install had no effect. I thought about doing a fresh install, but the amount of time for reinstallation of programs and drivers put me off the idea – this machine is my main development rig and I need it at 100% as much as possible.

It then occurred to me that maybe this was related to input in general, so why only the keyboard effected? I have a mouse and gamepad that didn’t cause any DPC latency spikes. I realized it was a PS/2 keyboard and all other input devices were on USB ports. Luckily I had a USB keyboard on my Mac that I could test with and, like magic, the latency spikes disappeared.

My long term solution? I don’t know. I’ll probably just get another USB keyboard. There’s a BIOS update available which I’ll probably try at a later date – BIOS updates scare me. It’s possible a fresh install of Windows may solve this as well, but I’m doubtful. I was surprised that the board got great reviews on Newegg and no one there or anywhere else on the web seems to have encountered similar issues with this board.


Let your app talk about itself

Fragment Sync has an automated update system called autobot. The system is used both for development and public releases (I should mentioned that automated updates to development copies of a networking app is a beautifully amazing thing). Updates are published to the autobot server using a simple publisher app, which puts the update package on the server and calls a server-side script to enter the patch details into a database. One annoyance with the publisher is that I would have to enter details (version, whether or not update is public, etc.) manually. This isn’t too bad, but on more than one occasion I’ve screwed things up by accidentally entering the wrong version or packaging an old executable.

I finally decided that the best way forward was to have the publisher automatically query the executable for information. You can embed this sort of information via. the application manifest, but using the manifest really didn’t cross my mind and I’m not a big fan of manifest files in general. In any case, what I did was have the executable take arguments and output the queried data to the console. This is a bit trickier than it sounds because, for whatever reason, a GUI app can’t send messages to a console without some hackery with the AttachConsole() Win32 function. (I’m dealing with C# and WinForms, but native Win32 GUI apps don’t have a default console either, so this isn’t a WinForms specific thing). The publisher redirected the standard output stream and read in the data that was pushed out.

This seems to have worked out nicely and has pushed me to think about other information an app can output about itself, lending to better communication between related apps.


Handle leaks and CreateProcess

I finally nailed down an annoying little bug tonight. In a certain app, I’ve been calling CreateProcess() to periodically spawn a process, do some work, and shut down. Unfortunately after running several hours, the app would fail with an exception saying: insufficient quota to complete the requested service. After a fair bit of monitoring the app’s activity, I notice that the handle count of the main process, slowly and surely, kept going up. After a bit of trial-and-error, disabling modules systematically, I finally noticed that this was occurring when I spawned off the child process I mentioned.

Reading the MSDN docs for CreateProcess(), I finally got to the root of the issue; the handles returned in the PROCESS_INFORMATION struct must be closed via. CloseHandle() or the handles are kept open, even though the child process has terminated.

If the function succeeds, be sure to call the CloseHandle function to close the hProcess and hThread handles when you are finished with them. Otherwise, when the child process exits, the system cannot clean up the process structures for the child process because the parent process still has open handles to the child process.

This oversight was probably due to the fact that I was working in C# (I was P/Invoking this stuff) and lulled into a false sense of safety, thinking the garbage collector would take care of stuff like this, but from working with files, various streams, sockets, etc. I realized that C# doesn’t really close handles automatically. Now that has me thinking, why not? Wouldn’t handle management be very similar to memory management?