Why is IIS Worker Process locking a file?

Answering my own question in case someone runs into this problem. Turns out web.config file had the <hostingEnvironment shadowCopyBinAssemblies="false" /> directive, which I didn't even know existed.

This setting tells IIS to execute everything in place rather than in Temporary ASP.NET Files folder.


A quick and reliable way to take down a site ready to deploy is to create a file in the root folder of your website called App_Offline.htm (~/App_Offline.htm). Content is optional, if present its served for all requests until the App_Offline.htm is deleted. This method will work under pretty much all cases - including any value used for shadowCopyBinAssemblies.

Basically App_Offline is a feature of IIS used by Web Deploy to ensure it can deploy correctly - avoiding any locking issues and such. It seems to operate at a very low level in IIS, its literally a file system watcher that kills the app pool. This means you can easily just create and delete this text file yourself without web deploy to stop and restart(or at least re-enable) your app.

Taken from MS docs:

When ASP.Net detects that a file by the name of "App_Offline.htm" exists, it will automatically bring down the app domain hosting the application. When the publish process is completed, the App_Offline.htm file will be removed and the site will be online again.

See Microsoft's article on taking an application offline.

Update - 22/5/2019

It might be worth pointing out by creating the app_offline file its causing 2 separate things to happen:

  1. IIS will instantly stop serving new requests and start returning a HTTP 503 "temporarily unavailable" response with the contents of the app_offline file.
  2. IIS starts a chain of events that leads to the termination of the instance of w3wp.exe - that is your "app domain" (as seen in task manager) - aka the owner of the locks. When that process dies, all locks are released. In my experience that's normally very quickly.

Based on personal/bitter experience of a few high traffic sites and as an absolute last resort... If for whatever reason an IIS site wont stop/release locks/abort existing requests its probably down to load or otherwise something blocking the process exiting - app_offline should kill the site very quickly under normal circumstances. In these cases, and assuming you know the requests wont complete, or you just dont care and need the site to stop or restart, create the app offline file, use task manager to kill the w3wp.exe process, perform your change, then remove the app offline file. The next request starts a new app domain (and obviously abandons any pending requests - so do this with caution - this may or not be a problem depending on your site).