Without getting into the 'Stateful services are bad' discussion... How do you create one?
From the lack of helpful search results.. it seems either I'm searching for the wrong terms or it is being actively discouraged. The best link i could find was this one on MSDN
To give a brief context of what my current app looks like. Rails Web App => ASP.Net Xml webservice => Legacy C#/C++ code
So far so good. Now it turns out that when I make the first request to a WebMethod, it needs to launch some processes/resources that are expensive to create-use-dispose on each call. So I was looking at reusing these resources.
First I tried making them into member variables - only to have the light-bulb moment that each request is serviced by a new instance of MyWebService
class and on a different thread at that.
The link suggests that the way to do this is
- to use the Session hash / properties collection in case the state is per-user.
- to use the Application hash / properties collection in case the state is global
Questions:
- Is this right? Am I missing some magic attributes ?
- I tried the Application hashtable method... populating certain known keys on the first request. However on the second request, the hashtable is in a clean/no items state.
- How do I handle Synchronization ? the .net way of locking on a private member object won't work.
My Web Service class looks like this..
[WebService(Namespace = "http://Walkthrough/XmlWebServices/",
Description="A temperature conversion xml web service")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class TemperatureConverter : System.Web.Services.WebService, IDisposable
{
[WebMethod(Description = "This method converts celsius to fahrenheit")]
public double convert_fahrenheit_to_celsius(double temp_in_fahrenheit)
{
/// code
}
}
Update: I'm still struggling with Q#2. There's some strange behavior
protected void Application_Start(object sender, EventArgs e) // global.asax.cs
{
Application["UserName"] = "Gishu";
}
myWebMethod // MyWebService.cs
{
if (Application["myKey"] == null)
LoadHeavyObjectsAndCacheKeys(); // set Application["myKey"] between Application.Lock() Unlock() calls.
...
}
The "UserName" key write succeeds - it is present in the hash. However the key-value pairs that I write within my web method don't survive the current web request. On the next request, the hashtable still has only one item - "UserName". Since this is ApplicationState, I assume I dont have to set the EnableSession property to true.