WCF实例化模式每个会话未按预期工作

时间:2013-01-03 00:55:36

标签: wcf instancecontextmode

我正在编写一个生成数据集的WCF应用程序,并允许客户端创建它们,浏览它们并从中检索数据。数据存储在服务类的静态变量中。特别地,它们存储在字典中,使用GUID字符串作为键。

我正在将服务类的实例化模式设置为PerSession,据我所知应该可以工作。客户端调用一个名为CreateRecordSet的函数,该函数向字典添加一个条目并返回密钥字符串。然后客户端调用一个名为First()的函数,该函数应该检索数据集中的第一条记录。但是,当它尝试这个时,字典不再包含任何条目。

奇怪的是,如果我将实例化模式设置为Single,它可以正常工作。但是,如果我将它设置为PerSession,它似乎会丢失两个调用之间的字典,如果我将它设置为PerCall,我会期望它。

这是界面定义:

namespace OrsonServiceLibrary
{
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string CreateRecordSet();

        [OperationContract]
        object First(string setkey);

        // Removed unused methods

    }

    [DataContract]
    [KnownType(typeof(JMMCustomer))]
    public class JMMCustomer
    {
        [DataMember]
        public string CUSTFNAME { get; set; }
        [DataMember]
        public string CUSTLNAME { get; set; }
        [DataMember]
        public string CUSTADDRESS { get; set; }
        [DataMember]
        public string CUSTCITY { get; set; }
        [DataMember]
        public string CUSTKEY { get; set; }

    }
}

这是服务类代码:

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
    public class Service1 : IService1
    {
        protected static Dictionary<String,RecordSet> RecordSets;

        public Service1()
        {
            RecordSets = new Dictionary<string,RecordSet>();
        }

        public string CreateRecordSet()
        {
            List<object> c = new List<object>(GetAllCustomers());
            var rs = new RecordSet(c);
            string thekey = System.Guid.NewGuid().ToString();

            RecordSets.Add(thekey, rs);

            Console.WriteLine("End of CreateRecordSet().  RecordSets.Count = " + RecordSets.Count);

            return thekey;
        }

        public object First(string setkey)
        {
            Console.WriteLine("Beginning of First().  RecordSets.Count = " + RecordSets.Count);

            if (RecordSets[setkey].thelist.Count < 1)
                throw new Exception ("No items in the data set.");
            else
                RecordSets[setkey].cursor = 0;

            return RecordSets[setkey].thelist[RecordSets[setkey].cursor];
        }

        // Removed unused methods
   }

这是客户端代码:

static void Main(string[] args)
{
    Console.WriteLine("Press Enter to begin.");
    Console.ReadLine();

    ServiceReference1.Service1Client MyService = new ServiceReference1.Service1Client("Service1");

    string sk = MyService.CreateRecordSet();

    ServiceReference1.JMMCustomer jc;
    jc = (ServiceReference1.JMMCustomer)MyService.First(sk);

    Console.WriteLine(jc.CUSTFNAME + " " + jc.CUSTLNAME);

    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
}

如您所见,我向主机的控制台添加了一些调试消息,以显示字典的状态。这是主持人的输出:

Host started.  Press Enter to terminate host.
End of CreateRecordSet().  RecordSets.Count = 1
Beginning of First().  RecordSets.Count = 0

当然,当我尝试引用RecordSets [setkey]时,我在First()的下一行代码中得到一个异常,因为RecordSets为空。

如果我将行为更改为:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]

......然后按预期工作。主机输出变为:

Host started.  Press Enter to terminate host.
End of CreateRecordSet().  RecordSets.Count = 1
Beginning of First().  RecordSets.Count = 1

...然后客户端按预期打印客户名称,没有错误。

那我错过了什么?我的理解是,只要我对两个调用使用相同的ServiceReference(MyService),如果服务器的InstanceContextMode设置为PerSession,它们应该在服务器上共享相同的静态变量。我不对吗?

-Joe

0 个答案:

没有答案