Monday, February 15, 2016

2016 New Primary Home PC Build!

With my family's primary home PC having been built in 2008 and showing its age, it was time earlier this month to build my first general-use home PC in 8 years!

Here's the parts list I put together and built, with a somewhat-flexible budget of around $1200:

Type Item Price
CPU Intel Core i7-4790K 4.0GHz Quad-Core Processor $339.99 @ Newegg
Motherboard MSI Z97-GAMING 5 ATX LGA1150 Motherboard $153.98 @ Newegg
Memory G.Skill Ripjaws X Series 16GB (2 x 8GB) DDR3-2133 Memory $74.99 @ Newegg
Storage (OS) Samsung 850 EVO-Series 250GB 2.5" Solid State Drive $87.99 @ Newegg
Storage (Apps) Western Digital 1TB 3.5" 7200RPM Internal Hard Drive $59.99 @ Office Depot
Storage (Data) Western Digital Blue 4TB 3.5" 5400RPM Internal Hard Drive $133.99 @ Newegg
Video Card EVGA GeForce GTX 970 4GB SSC ACX 2.0+ Video Card $333.98 @ Newegg
Power Supply EVGA 500W 80+ Bronze Certified ATX Power Supply $29.99 @ Newegg
Optical Drive Asus DRW-24B1ST/BLK/B/AS DVD/CD Writer $15.99 @ Newegg
Operating System Microsoft Windows 10 Home OEM (64-bit) $102.98 @ Newegg
Total   $1333.87

I had a spare case and existing mouse / keyboard / monitor / speakers to use with this build, so I didn't need to factor those in.

The website pcpartpicker.com (the target of all of the links in the parts list above) was a particularly helpful tool in keeping track of the parts for this build as I was researching and selecting them!  It was a nice upgrade over the text file and/or spreadsheet-based systems I’ve used for this in the past.

Photos!

In chronological order of how I executed the build!

The goods, prior to the build.  (Note: The LEGO blocks pictured were not actually included in the build.)

Goods

The empty case – with its circa 2006 350W power supply with only IDE power cables, no SATA, removed – ready for components!

EmptyCase

Motherboard in place and screwed down!

MotherboardInCase

The Intel Core i7 CPU, still in packaging.  That’s a lot of power packed into a small package!

CPU

Close-up of CPU installed in motherboard.

CpuInMotherboard

CPU locked into place (via the lock included as part of the motherboard).

CpuInMotherboardLocked

CPU with thermal paste applied and then fan installed on top.

CpuInstalledWithFan

New power supply installed in case and wired up to motherboard.  It isn’t very visible in this photo, but the CPU wires for the power switch, reset switch, and the front USB 2.0 ports are also wired to the motherboard in this photo, on the bottom edge.

PowerSupplyInstalled

The solid state drive (SSD) and traditional hard disk drive (HDD) drive side-by-side.  Even though this wasn’t my first SSD install, I was surprised anew just how small, thin and light that drive is compared to the traditional HDD.

HDDandSSD

Drives installed in case.  This older case didn’t have a spot designed to accommodate the SSD, but that drive was small and light enough that I was comfortable with just screwing one side of it into the 3.5” HDD bay (at an angle to get the screw holes to line up!).  The optical (CD/DVD) drive is also installed in the top 5.25” slot.

DrivesInstalled

The G.Skill Ripjaws 2 x 8GB RAM installed (just to the right of the big CPU fan).  Not sure how much faster the fancy red trim makes it, but it does look cool!

RAMInstalled

The GeForce GTX 970 video card, just out of its packaging.  This thing is a beast, size-wise!  Clearly EVGA wants it to look nice out of the box, since it came with clear plastic wrap over the entire thing (a couple of pieces of which are still on and visible in this photo, such as the piece over the “GeForce GTX 970” logo on the bottom edge).

VideoCard

Video card installed.  It turned out to be juuust big enough in this case that I couldn’t quite install a full size hard drive directly across from it (even using a 90-degree SATA cable).

VideoCardInstalled

Finally, everything assembled, with the cover on over the rear-facing motherboard ports.  Both the motherboard and video card came with caps installed over their video ports (as shown here), which I appreciated.

Rear

Mishaps and Mistakes

DOA HDD

So with everything assembled and monitor, keyboard, mouse, power, network, and speakers all plugged in, I hit the power button for the first time… and immediately noticed two obviously “unhappy” sounds:

  1. A buzzing-type sound coming from the bottom portion of the case;
  2. A repetitive squealing / grinding sound coming from the front of the case.

The first sound turned out to be easily solvable; one of the case wires at the bottom of the case was contacting the spinning fan on the underside of the video card.  Getting those wires out of the way solved that.

Unfortunately, the second noise turned out to be the sound of a dead hard drive.  The noise was coming from the 2TB HDD.  It wouldn’t stop making the noise, and the drive wasn’t recognized by the BIOS (whereas the SSD and the optical drive were recognized with no issues).

This was my first DOA (“dead on arrival”) part among the five PC builds I’ve done, so I suppose I was due. I got it returned and refunded with no issues… and ended up breaking my budget a bit by replacing it with both a fast 7200 RPM 1 TB drive for installing programs, and a 5600 RPM 4 TB drive for storing all the great photos my wife takes.

Forgotten Thermal Paste

Fortunately, I didn’t forget to apply thermal paste, which might have resulted in a cooked CPU.  Rather, I forgot to order thermal paste.  None came with the CPU I bought, and I only do PC builds infrequently (every few years) and so didn’t have any on hand.

Also fortunately, my town has a little PC repair shop, and so one quick car trip and $1 later I was good to go with a single-use tube of thermal paste.

Don’t Leave the Motherboard Backplate For Last

With this build, I made the embarrassing mistake of leaving the install of the motherboard backplate (which ends up situated over all of the ports on the back of the PC) for last, thinking for whatever reason that I could pop it into place from the rear.

However, I realized the hard way that the backplate does not install from the rear; rather, it needs to go on from the inside of the case, before the motherboard gets fastened into place.

So, to my chagrin, I ended up unscrewing the motherboard from the case (leaving everything else connected), shifting it slightly to allow the backplate to be installed, and then positioning it back into place and screwing it back in.  And so, oddly enough, this build came full circle, in that affixing the motherboard to the case was both the first and the last step!

So How’s it Working?

It’s working great!  I haven’t measured it yet, but Windows 10 boots incredibly fast. 

The app where I’ve seen the most difference relative to my old PC is the game Cities: Skylines (the latest and greatest take on the city-builder genre pioneered by SimCity).  On the old PC, saved games would take a very long time to load, and the game itself was quite playable but it would “chug” noticeably, particularly when trying to rapidly scroll around the map.  On the new PC, by contrast, it’s super fast and smooth as silk!

After doing “main home PC” replacements every 4 years (in 2000, 2004, and 2008), that 2008 model lasted for a solid 8 years.  (It’s actually still running, although there are signs it might be on its last legs, which helped prompt this upgrade).

I’m hoping this new PC has a nice long life as well!  I’d like it to still be running in 8 years… at which point my 10-year-old will be headed off to college.  Now there’s an interesting thought!

Wednesday, January 27, 2016

Entity Framework perf tip: Turn off AutoDetectChangesEnabled when doing bulk inserts

I was working on a situation this morning where, as part of a C# unit test method using Entity Framework 6 for database access, I was inserting about 1000 records into a SQL Server database.

This test was taking around 30-35 seconds to run, and I wanted to speed it up.  I tried re-coding the program to do the inserts using raw SQL, and that sped things up by about a factor of 3.

Thanks to a tip I found in a StackOverflow answer by “Steve”, I was able to get the same perf increase using Entity Framework by simply disabling AutoDetectChangesEnabled:

mycontext.Configuration.AutoDetectChangesEnabled = false;

Doing that before the loop with my calls to .Add() sped up the EF code to the point where it was performing just as well as the raw SQL. 

So, in situations where you’re using EF to do lots of inserts and you don’t need AutoDetectChangesEnabled (because you’re not also doing any updates to existing records), try turning it off for a possible nice performance improvement.

More info on this from Microsoft EF team member Arthur Vickers: Secrets of DetectChanges Part 3: Switching off automatic DetectChanges

Wednesday, January 06, 2016

Configuring ASP.NET applications in IIS to accept requests with long URLs

When creating a RESTful web service with a GET method accepts a variable-length list of parameters, it can happen that URLs generated to call the service – including the query string containing the paremters – can end up being very long. 

I’m working on a REST method with a parameter that accepts a comma-delimited list of up to 2000 ID values.  With ID values being up to 7 characters in length, the URL for a request with the maximum 2000 7-character ID values, plus an 8th comma separator character after each ID value, ends up being 16000+ charaters long.  For example:

http://mysite.example.com/api/products&productIDs=1000001,1000002,100003,…many more IDs here!…,1001999,1002000

After running into multiple obstacles trying to get my ASP.NET application running on IIS to successfully accept such incoming long request URLs without throwing errors, I’ve come to the conclusion that in situations like this, it’s better to have the API method accept HTTP POST instead of HTTP GET, and have the client pass the list of parameters in the message body intead of in the URL. This approach aligns with answers on Stackoverflow to the question Design RESTful GET API with a long list of query parameters.

However, I figured I’d go ahead and post the data I collected while troubleshooting the various errors that ASP.NET and IIS can return when a request with a long URL is submitted, in case I need this information again in the future, or in case it might help anyone else.

In all cases, the specific configured values (e.g. ”65535”) should be tailored to the specific needs of your application. Be aware that setting these values could have adverse security consequences for your application, as a large HTTP request submitted by an attacker won’t be rejected early in the pipeline as it would normally.

All of this investigation was done with an ASP.NET application targeting .NET Framework 4.5.1, running on IIS 10, on a Windows 10 64-bit PC.
 

Symptom 1

Response HTTP status code: HTTP 414

Response body: HTTP Error 414. The request URL is too long.

Relevant response header: Server: Microsoft-HTTPAPI/2.0

Fix 1

In the Windows Registry, at Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters, create a DWORD-type value with name MaxFieldLength and value sufficiently large, e.g. 65535.

Note: This error is actually thrown by http.sys, before the request even gets passed along to IIS in the request-handling pipeline.  Thus, web.config settings aren’t able to address this particluar error.  See article Check the “Server” HTTP header for the source of an error returned from IIS.

If you decide to make this change, then obviously it’ll need to be made in all environments (including all production server(s)) -- not just on your local dev PC.  Also, whatever script and/or documentation your team uses to set up new server instances will need to be updated to include this registry setting, so that your team doesn’t forget to apply this setting 18 months from now when setting up a new production server. (This was a big reason that for the API I’m building, I opted to just scrap the long-GET-URL approach, and make my method a POST instead.)

References:

 

Symptom 2

Response HTTP status code: HTTP 404

Response body: (Empty)

Relevant response headers:

Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET

Fix 2

In web.config, add the following configuration (modifying existing elements when they are present, otherwise adding new elements):

<system.webserver>
  <security> 
    <requestFiltering> 
      <requestLimits maxQueryString="65535" /> 
    </requestFiltering> 
  </security> 
</system.webServer>

References:

Note: In my ASP.NET solution, I needed to make this change in my root project’s web config. This setting was ignored when I added the change in my API sub-project’s web.config.  (This however was not the case for the web.config change mentioned in “Fix 3” below.)  Related MSDN article: ASP.NET Configuration File Hierarchy and Inheritance

 

Symptom 3

Response HTTP status code: HTTP 400

Relevant response body text snippets:

System.Web.HttpException: The length of the query string for this request exceeds the configured maxQueryStringLength value.

[HttpException (0x80004005): The length of the query string for this request exceeds the configured maxQueryStringLength value.] System.Web.HttpRequest.ValidateInputIfRequiredByConfig() +492 System.Web.PipelineStepManager.ValidateHelper(HttpContext context) +55

Relevant response headers:

Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

Fix 3

In web.config, add the following configuration (modifying existing elements when they are present, otherwise adding new elements):

<system.web> 
  <httpRuntime maxRequestLength="65535" maxUrlLength="65535" maxQueryStringLength="65535" />
</system.web>

Tuesday, January 05, 2016

Check the “Server” HTTP header for the source of an error returned from IIS

When an error response is returned from an HTTP request submitted to an IIS web server, the error response might actually be coming from http.sys (the “Hypertext Transfer Protocol Stack”), which processes incoming HTTP requests before they are passed along to IIS.

You can determine the source of the error by looking at the “Server” HTTP header in the returned HTTP response.  An error coming from http.sys will have the header:

Server:Microsoft-HTTPAPI/2.0

An error coming from IIS will instead have a header like:

Server:Microsoft-IIS/XX.X

Here’s some handy C# code to dump all headers from a given WebResponse to the console:

for (int i = 0; i < response.Headers.Count; i++) 
{ 
    string header = response.Headers.GetKey(i); 
    string[] values = response.Headers.GetValues(i); 
    Console.WriteLine(header + ": " + String.Join(", ", values)); 
}

Bonus tip: For a bit more information on errors generated by http.sys, check out the log files in this folder on the web server PC:

%windir%\System32\LogFiles\HTTPERR

References:

Wednesday, December 23, 2015

Developer Tip: Orient Your Monitor Vertically!

On my development machine, I have an external monitor physically set up in vertical / portrait orientation, instead of the “default” horizontal / landscape orientation.  My IDE (code editor) window always resides on that monitor.

Instead of writing 1000 words to explain why this works great, I’ll let a pair of pictures do most of the explaining for me.

Here’s a Visual Studio window (with the code for my open-source “Schneider’s Eleven” minimalist skin for Windows Media Player) open on my horizontal-orientation monitor at 1920x1080 resolution:

VSHorizontal2

Look at all that wasted whitespace on the right half of the main code pane!  (This code was admittedly developed using fairly short line lengths, but the same wasted space effect probably still applies to at least some extent in the majority of projects out there.)

Now, here’s the exact same Visual Studio window moved over to my vertical-orientation 1200x1920 monitor:

VSVertical1

Much less wasted whitespace!  And almost 100 lines of code are visible on the screen at the same time, making it much easier to visually scan a large chunk of source code without having to scroll around.

Having developed code this way in both Windows and Mac OS environments, I’d never go back!  Rotating a particular monitor 90 degrees is an easy configuration change in the OS display properties (in Windows, Mac OS, and evidently in Linux as well), so if your physical display stand supports it, I’d encourage giving it a try and seeing how it works for you!