网络世界,大有可为

献给自己的一片天空

导航

WebService的状态管理(转)

关于WebService的状态管理,园子里也有不少文章了,正好今日要做一个关于状态管理的调查,现在老了,记忆力不如以前好了,因此顺便把自己的一些理解写下来,以防遗忘。
众所周知,WebService的调用是无状态的,即WebService中的变量是不能做到跨方法使用的。但是我们在实际的项目中,难免会遇到跨方法使用某些变量的情况,所以我们应该想办法治好WebService的失忆症,用什么药好呢?
当仁不让,首先应该想到使用Application。Application对于WebService是始终可用的,而且使用起来也非常方便,不需要做任何的配置。
服务器端代码:

public class StateService : System.Web.Services.WebService
{
    public StateService()
    {
    }

    [WebMethod]
    public string Hello() 
    {
        return "你好," + Application["name"].ToString();
    }

    [WebMethod]
    public void SetName()
    {
        Application["name"] = "笨笨熊";
    }
}
客户端代码:

class Program
    {
        static void Main(string[] args)
        {
            StateService.StateService firstService = new TestProject.StateService.StateService();
            firstService.SetName();
            Console.WriteLine(firstService.Hello());
            Console.Read();
        }
    }
运行结果:你好,笨笨熊
由上面的代码可以看出,Application确实有疗效,但是有没有副作用呢?Application是作用于整个应用程序域的,因此里面的东西是对所有人可见的,并且只有应用程序结束(IIS Stop)才会自动清除里面的对象。这就给保密性和性能带来了一些问题,毕竟有时候我们希望自己的东西不能让别人看。那就要用到Session了。
使用Session要做一些简单的配置。首先要使用EnableSession=true来标识WebMethod可以使用Session;其次是要在客户端用CookieContainer关联Session。(当然,没有在WebMethod上EnableSession=true,不代表Session不存在,其实Session也是存在于服务器端的,只不过是不能使用而已。)
注意:即使你的变量没有到客户端使用,也要在客户端设置CookieContainer才可以。
服务器端代码:

public class StateService : System.Web.Services.WebService
{
    public StateService()
    {
    }

    [WebMethod(EnableSession=true)]
    public string Hello() 
    {
        return "你好," + Session["name"].ToString();
    }

    [WebMethod(EnableSession=true)]
    public void SetName()
    {
        Session["name"] = "笨笨熊";
    }
}
客户端代码:

class Program
    {
        static void Main(string[] args)
        {
            StateService.StateService firstService = new TestProject.StateService.StateService();
            firstService.CookieContainer = new System.Net.CookieContainer();
            firstService.SetName();
            Console.WriteLine(firstService.Hello());
            Console.Read();
        }
    }
运行结果:你好,笨笨熊
以上是两种方式的实现,但下面来深入地探讨一下Session方式:
Session中对象的访问界限是怎么样的呢? 让我们做一下验证:
服务器端代码:

public class StateService : System.Web.Services.WebService
{
    public StateService()
    {
    }

    [WebMethod(EnableSession=true)]
    public string Hello() 
    {
        string strReturn = string.Empty;
        try
        {
            strReturn = "你好," + Session["name"].ToString();
        }
        catch (NullReferenceException ex)
        {
            strReturn = "你好";
        }
        return strReturn;
    }

    [WebMethod(EnableSession=true)]
    public void SetName()
    {
        Session["name"] = "笨笨熊";
    }
}
客户端使用以下方式调用:

class Program
    {
        static void Main(string[] args)
        {
            StateService.StateService firstService = new TestProject.StateService.StateService();
            firstService.CookieContainer = new System.Net.CookieContainer();
            firstService.SetName();
            Console.WriteLine(firstService.Hello());
            firstService.CookieContainer = new System.Net.CookieContainer();
            Console.WriteLine(firstService.Hello());
            Console.Read();
        }
    }
这种调用方式的运行结果是:
你好,笨笨熊
你好
由此可以看出,Session中的变量访问界限和客户端的CookieContainer有着直接的关系,但是和WebService的代理类的实例有没有关系呢?我们修改一下客户端调用的代码,如下:

class Program
    {
        private static System.Net.CookieContainer m_CookieContainer = new System.Net.CookieContainer();
        static void Main(string[] args)
        {
            StateService.StateService firstService = new TestProject.StateService.StateService();
            firstService.CookieContainer = m_CookieContainer;
            firstService.SetName();
            Console.WriteLine(firstService.Hello());            
                StateService.StateService secondService = new TestProject.StateService.StateService();
            secondService.CookieContainer = m_CookieContainer;
            Console.WriteLine(secondService.Hello());
            Console.Read();
        }
    }
运行结果:
你好,笨笨熊
你好,笨笨熊
这就说明Session中的变量访问界限是取决于客户端的CookieContainer的实例的,跟WebService的代理类的实例没有关系。当然,这也不过是访问的界限问题,至于Session中变量的销毁还是要考虑的,仅仅依靠Session TimeOut时间是不够的,很多时候还要通过自己写代码释放资源。

posted on 2007-05-28 16:45  Geerry  阅读(201)  评论(0)    收藏  举报