Resolved JobContext.Flush() issues and implemented per-user persistent sessions

* Unnecessary calls to JobContext.Flush() were resulting in Sitecore Jobs which did not terminate, eventually throwing a ThreadAbortException and leading to death of the Sitecore worker thread. If this happens enough times, Sitecore would run out of worker threads.
* Fixing this exposed some issues with early disposal of persistent sessions, which were resolved.
* To avoid persistent sessions being shared between users, also implemented a session key which includes the HTTP session ID of the current user, if present.
* Also implemented a cache timeout for persistent sessions.