Search code examples
c#web-servicespersistenceobject-persistencestateful

Is it possible to create stateful web service in C#?


I have now something like this:

public class Service1 : System.Web.Services.WebService
{
    [WebMethod]
    public string Method1()
    {
        SomeObj so = SomeClass.GetSomeObj(); //this executes very long time, 50s and more
        return so.Method1(); //this exetus in a moment 
    }

    [WebMethod]
    public string Method2()
    {
        SomeObj so = SomeClass.GetSomeObj(); //this executes very long time, 50s and more
        return so.Method2(); //this exetus in a moment 
    }

 ...
}

Is it possible to make stateful web service so that I can reuse SomeObj so and just call methods on the same object?

So the client which will use this service would first call web method which would create so object and return some ID. And then in subsequent calls the web service would reuse the same so object based on ID.

EDIT


Here is my actual code:

[WebMethod]
public List<ProcInfo> GetProcessList(string domain, string machineName)
{
    string userName = "...";
    string password = "...";
    TaskManager tm = new TaskManager(userName, password, domain, machineName);

    return tm.GetRunningProcesses();
}

[WebMethod]
public bool KillProcess(string domain, string machineName, string processName)
{
    string userName = "...";
    string password = "...";
    (new TaskManager(userName, password, domain, machineName);).KillProcess(processName);               
}

Solution

  • Stateful web services are not scalable and I wouldn't recommend them. Instead you could store the results of expensive operations in the cache. This cache could be distributed through custom providers for better scalability:

    [WebMethod]
    public string Method1()
    {
        SomeObj so = TryGetFromCacheOrStore<SomeObj>(() => SomeClass.GetSomeObj(), "so");
        return so.Method1(); //this exetus in a moment 
    }
    
    [WebMethod]
    public string Method2()
    {
        SomeObj so = TryGetFromCacheOrStore<SomeObj>(() => SomeClass.GetSomeObj(), "so");
        return so.Method2(); //this exetus in a moment 
    }
    
    private T TryGetFromCacheOrStore<T>(Func<T> action, string id)
    {
        var cache = Context.Cache;
        T result = (T)cache[id];
        if (result == null)
        {
            result = action();
            cache[id] = result;
        }
        return result;
    }