Mount .iso files in Windows

I remember Greg Low once talking about the “Resolved: by Design” or “Resolved: as Won’t Fix” replies on Connect when the issue being raised or asked for was clearly a good idea (obviously there are time constraints and sometimes things just aren’t possible); his point was that it doesn’t take too many such responses for even someone evangelical in their conscientious raising of issues to be less than enthusiastic about continuing to do so.

Why do I mention that? Well, ever wanted to mount an .iso file natively in windows? Not such a surprising thing to want to do, right? Especially as Microsoft actually provide many downloads in this format (such as the Windows 7 OS, which is what I was installing). Check out this Connect article “Mount .iso files”. It had 919 up-votes at last count!… Something for Windows 8?

I resorted to using one of the many third party installs which do the job: Virtual CloneDrive. But it really does feel like this should be part of Windows. Getting community/user feedback on your products is a great way to improve them, but only if you’re listening.

“Thank you for your comment/suggestion.
We will continue to monitor your submission and when it reaches the vote threshold from the community we will forward it to the appropriate feature team. We will also respond here to let you know it has been escalated.”

I wonder what that vote threshold is!

Free ASP.NET MVC2 Book

Apparently a very good book on ASP.NET MVC 2 is “MVC 2 In Action” from Manning, and while the authors are putting the finishing touches to the MVC 3 version of the book, the entire MVC 2 version is available completely free in Word document form at: https://github.com/jeffreypalermo/mvc2inaction.

Every version of MVC relies on the previous version (except with a few breaking changes), so there is still value in reading this free resource.

Jeffrey Palermo’s original post is here.

TSQL: Finding Maximum, Minimum and Average Data Row Lengths

This is probably a classic example of if you find you are doing something complicated, there’s almost certainly a better way. It’s also an example of if you think something is genuinely useful and can’t understand why it’s not been implemented already, it probably has but you just haven’t found it yet!

I wanted to get a table’s approximate minimum, maximum and average row size, so after a few attempts I came up with this TSQL snippet:

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

declare @schemaname varchar(200) = 'Person'
declare @tablename varchar(200) = 'Person'
declare @columnList nvarchar(max)
declare @sql nvarchar(max)

set @columnList =
stuff(
( SELECT
' + ISNULL(DATALENGTH(' + c.name + '),0)'
FROM
sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
where SCHEMA_NAME(schema_id) = @schemaname and t.name = @tablename
for xml path('')
)
, 1, 3, '')

SET @sql = 'SELECT ''' + @schemaname + '.' + @tablename + ''' as TableName,' +
' MIN(' + @columnList + ') AS MinRowLength, ' +
' MAX(' + @columnList + ') AS MaxRowLength, ' +
' AVG(' + @columnList + ') AS AverageRowLength ' +
' FROM [' + @schemaname + '].[' + @tablename + ']'
EXEC sp_executesql @sql

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

[Note: It’s not 100% accurate due to some row overheads, but it is close enough for many purposes.]

At which point, the thought “Surely there exists a built-in method to do this?” crossed my mind, and of course there is!

If you have sufficient permissions you can quickly produce a min, max and average row size for each table in a database (along with fragmentation information) using

   DBCC SHOWCONTIG WITH TABLERESULTS

Online IDE for 40+ languages

It’s not often I don’t have access to the Visual Studio IDE, but I saw Jon Skeet mention this recently on SO: http://ideone.com/

What is ideone?
Ideone is something more than a pastebin; it’s an online compiler and debugging tool which allows
to compile and run code online in more than 40 programming languages.

Large Object Heap and Arrays of Double

If you were asked where objects greater than or equal to 85,000 bytes are allocated in .NET, you would no doubt say on the Large Object Heap (LOH). What would you say if you were asked where an array of 1000 doubles would be allocated? Currently, as of .NET 4.0, it will be allocated on the Large Object Heap!

William Wegerson (aka OmegaMan), a C# MVP, posted this item to Connect: Large Object Heap (LOH) does not behave as expected for Double array placement that describes and reproduces the behaviour:

byte[] arrayLessthan85K = new byte[84987]; // Note: 12 byte object overhead 84987 + 12 = 84999
Console.WriteLine("byteArrayLessthan85K: {0}", GC.GetGeneration(arrayLessthan85K)); // Returns 0

byte[] array85K = new byte[85000];
Console.WriteLine("byteArray85K: {0}", GC.GetGeneration(array85K)); // Returns 2

double[] array999Double = new double[999];
Console.WriteLine("array999Double: {0}", GC.GetGeneration(array999Double)); // Returns 0

double[] array1000double = new double[1000];
Console.WriteLine("array1000double: {0}", GC.GetGeneration(array1000double)); // Returns 2

By looking at the garbage collection generation on object creation (GC.GetGeneration), we can identify if objects reside the LOH or not. If immediately created in generation 2 then that suggests we are in the LOH.

The reason why double arrays with 1000 or more items are allocated on the LOH is performance, due to the fact that the LOH is aligned on 8 byte boundaries. This allows faster access to large arrays and the trade-off point was determined to be 1 thousand doubles.

According to Claudio Caldato, CLR Performance and GC Program Manager, “there’s no benefit to applying this heuristic on 64-bit architectures because doubles are already aligned on an 8-byte boundary”. Subsequent changes have been made to this heuristic that should appear in a future release of the .NET Framework.

As a side note, the expected behaviour is seen if you use Array.CreateInstance() :

// As noticed by @Romout in the comments to that post, the same behaviour is not seen when using Array.CreateInstance()
double[] array1000doubleCreateInstance = (double[])Array.CreateInstance(typeof(double), 1000); // Returns 0
Console.WriteLine("With array-create: " + GC.GetGeneration(array1000doubleCreateInstance));

// Indeed, the expected tipping point into the LOH occurs when using Array.CreateInstance
// (85000 / 8) = 10625, need 12 bytes for object overhead, nearest is 16 (2*8) bytes so effectively 10623 doubles
double[] array1000doubleCreateInstance2 = (double[])Array.CreateInstance(typeof(double), 10623); // Returns 0
Console.WriteLine("With array-create: " + GC.GetGeneration(array1000doubleCreateInstance2));

double[] array1000doubleCreateInstance3 = (double[])Array.CreateInstance(typeof(double), 10624); // Returns 2
Console.WriteLine("With array-create: " + GC.GetGeneration(array1000doubleCreateInstance3));

Newline in Summary XML

You probably know this already, but just in case you don’t! If you want line breaks in your popup tooltip descriptions in Visual Studio, you add the element to your XML summary comments e.g.:

///  
/// Main comment
/// Line 1
/// Line 2
///

public bool SomeProperty { get; set; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

and it appears like this:

VSToolTip

SQL Server Compact Toolbox

If you are using SQL Server Compact Edition (CE), and have not seen this already, the SQL Server Compact Toolbox is a Visual Studio 2010 Pro or higher add-in (for SQL Server CE 3.5/4.0) and standalone app (for 4.0), that adds scripting, import, export, migrate, rename, run script, manage replication and more to your SQL Server Compact Data Connections in VS Server Explorer.

Written by Erik Ejlskov Jensen who’s aptly named blog, Everything SQL Server Compact, contains a wealth of tips, tricks and techniques relating to SQL Server Compact.

The toolbox adds several features to Server Explorer:

Scripting:

  • Script tables, including data, both DDL and DML
  • Script entire schema, optionally with data, from SQL Server Compact and SQL Server 2005/2008 databases
  • Import to SQL Server Compact from a SQL Server 2005/2008 database or a CSV file
  • Migrate from SQL Server Compact to SQL Server and SQL Azure
  • Migrate from SQL Server to SQL Server Compact
  • Create database diff scripts, compare with a SQL Server Compact or even a SQL Server database

Query editing:

  • Basic, free form query execution
  • Editor with syntax colouring
  • Parse SQL scripts
  • Display graphical estimated and actual execution plan
  • Check query duration

Other features:

  • Rename tables
  • Generate detailed DGML files for visualizing table columns and relationships (requires VS 2010 Premium or higher to view)
  • Generate an Entity Data Model (EDMX) in the current project for both 3.5 and 4.0 in any applicable project (WPF, WinForms, Class Library)
  • Remove invalid connection definitions from the Toolbox (and Server Explorer)
  • Create and manage SQL Server Merge Replication subscriptions
  • Data types node with documentation tooltips lists the 18 available data types
  • File version check (for version 2-4)
  • Upgrade version 3.x files to version 4 via the “Add version 4 connection” dialog
  • About dialog with detailed SQL Server Compact version information

Another of his posts, SQL Compact 3rd party tools, lists several 3rd party tools for CE, both commercial and non-commercial.