From time to time I listen to the .NET Rocks show – I don’t get the chance to listen every week, but I do browse through the RSS items I get for the show episodes and find some time to put those I find of particular interest on in the background while I’m working on something else.
Yesterday’s episode caught my eye, as it focused on the nKinect project, exposing the Kinect’s capabilities to .NET. And ’m really (and I mean really) excited about the Xbox Kinect. I mentioned it in passing in a post from last March (it was still called Project Natal, back then) and it’s pretty clear to me that this device – and those like it – are set to change the industry. I’ve had a Kinect on order since the beginning of December (frustratingly you can’t get the Xbox 360 S 250Gb Kinect bundle, here, for love nor money), but in the meantime I’m having to be content with seeing what other people are managing to do with them. In particular the work of Oliver Kreylos is really worth checking out. There there's all the fun stuff on Kinect Hacks... from the ability to control applications, Minority Report-style to the potentially even more useful ability to transform yourself into a Japanese Super-Hero. :-)
While it’s the nKinect interview – which turned out to be a little disappointing due to its slight lack of fluidity – that caused me to listen to the episode, there was one piece of information earlier in the show that really got my attention: in the regular “Better Know a Framework” segment, Carl Franklin mentioned System.Runtime.MemoryFailPoint, a .NET Framework class that can be used to check for available memory prior to calling a memory-consuming operation.
I decided to give it a go, wrapping it into a helper function to simplify the memory check.
Here’s the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Runtime;
using System;
namespace MemoryHog
{
public class MemoryConsumingApp
{
// Helper function to check for adequate memory
bool CanGetMemory(int megabytes)
{
try
{
MemoryFailPoint mfp = new MemoryFailPoint(megabytes);
}
catch (InsufficientMemoryException)
{
return false;
}
return true;
}
[CommandMethod("MEM")]
public void CheckForMemoryBeforeRunning()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Ask for the amount of memory for which to check
PromptIntegerOptions pio =
new PromptIntegerOptions(
"\nEnter amount of memory (in megabytes) to check for: "
);
pio.AllowNegative = false;
pio.AllowNone = false;
pio.AllowZero = false;
PromptIntegerResult pir = ed.GetInteger(pio);
// Check for the memory
bool canProceed = CanGetMemory(pir.Value);
ed.WriteMessage(
"\n{0}ufficient memory to complete operation.",
canProceed ? "S" : "Ins"
);
if (!canProceed) return;
// Perform operation
// ...
}
}
}
I ended up adding some code to prompt the user for the amount of memory (in megabytes) for which to check, mainly as it gives the chance to vary the amount and is therefore more interesting to play around with. In your applications you’ll have the interesting job of calculating the amount of memory a particular task will require.
I structured the code at the end of the command to show the kind of logic I would use to test for sufficient memory and then return from the command, should it not be available.
Here’s some fun I had using this MEM command to determine how much memory is available to my application during an AutoCAD session with various other applications running on my 32-bit Vista system:
Command: MEM
Enter amount of memory (in megabytes) to check for: 50
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 100
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 150
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 300
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 200
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 250
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 280
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 290
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 295
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 298
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 299
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 300
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 301
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 310
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 320
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 330
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 340
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 360
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 380
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 400
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 500
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 450
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 470
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 480
Sufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 490
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 485
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 483
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 482
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 481
Insufficient memory to complete operation.
Command: MEM
Enter amount of memory (in megabytes) to check for: 480
Sufficient memory to complete operation.
I tried to zero in on the amount of memory available, but as you can see (and as is logical), this amount fluctuates according to (or inversely to, I suppose) memory usage. I started zeroing in on a number at around 300Mb, but the number I eventually ended up with was 480Mb (and this was after a session where the application only had around 70Mb available to it).
This really isn’t intended as an interactive tool to determine what memory is available, but I thought I’d just mention these results as an aside.