You can definitely do this by using a facade to the Request and Session data. It would require you to change all of the code in your page to use the facade instead of calling Request or Session directly, however.
When launching the separate thread, create a new (custom) SessionData object which stores all the info you need about Request and Session, and store it in a database or HttpRuntime.Cache. Pass the identifier for that object into your thread, so that thread knows which SessionData object to use.
If you are in your special worker thread, you can instantiate your SessionFacade with the ID. Otherwise, instantiate it with no parameters.
Here's an example of the SessionFacade, hopefully enough to get you started:
class SessionFacade
{
private string _threadID;
public SessionFacade() { }
public SessionFacade(string threadID)
{
this._threadID = threadID;
}
public object this[string key]
{
get
{
return this.GetData(key);
}
}
protected object GetData(string key)
{
if(!string.IsNullOrEmpty(this._threadID))
{
return ((SessionData)HttpRuntime.Cache[this._threadID])[key];
}
else
{
return Session[key];
}
}
}