When exactly does Application_End get called and how can I manually cause this?
Like Nick said, "An application pool will recycle when... some of the recycle limits are hit on the application pool configuration." In IIS you can set the recycling conditions in the application pool settings. You can use fixed intervals (every X minutes or requests), a specific time of day, or memory-based maximums in MB (max virtual memory or max private memory), or a combination of any of these. You can also set an idle time-out in minutes after which a worker process is terminated.
An application pool will recycle when you change the web.config or the /bin directory, or some of the recycle limits are hit on the application pool configuration. The same is true for Cassini except it doesn't have an application pool, so it will trigger any time the web.config or /bin directory is changed. I am not sure about killing the instance of Cassini.