如何在WCF Web服务中共享数据

时间:2011-11-22 09:51:24

标签: c# wcf web-services static thread-safety

为了动态调用webservices,我使用WCF Dynamic Proxy from Microsoft

如果我理解它是如何工作的,代码加载wsdl并在系统类上编译以使用远程webservice。我将此代码放在“通用Web服务”中。它的目标是在参数中调用带有请求的任何web服务,并响应所调用的web服务的答案。

但是出现了一个问题:对这个“通用web服务”的每个请求都会提取代理的新编译,并使用服务器的时间和资源。

我的目标是在一段时间内保存每个代理的实例,并在达到此圈时更新实例。

经过几个小时的谷歌搜索,我找到了两种方法:

  • 使用我的WCF网络服务“按会话”,但我找不到任何解释如何轻松创建会话层的教程
  • 使用单身人士来保存我的数据并将其与所有webservice实例进行互动

我排除了第一个解决方案,因为我不知道该怎么做。所以我决定使用第二种方式。

有我的实施:

  • FactoryTest是单例,用实例
  • 来竞争哈希表
  • ProxyTest是包含有关远程Web服务的每个实例的信息的类

有FactoryTest的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WcfSamples.DynamicProxy;
using System.Threading;
using System.Collections;

namespace WS_Generic
{
    public sealed class FactoryTest
    {
        private static object syncRoot = new Object();
        private static Hashtable hashFactory = new Hashtable();

        public static DynamicProxy getProxy(String sServiceWsdl, String sContract)
        {
            if (hashFactory[sServiceWsdl] == null || ((ProxyTest)hashFactory[sServiceWsdl]).getTimeFromCreation().TotalSeconds > 60 * 60 * 6)
            {
                lock (syncRoot)
                {
                    if (hashFactory[sServiceWsdl] == null || ((ProxyTest)hashFactory[sServiceWsdl]).getTimeFromCreation().TotalSeconds > 60 * 60 * 6)
                    {
                        hashFactory.Add(sServiceWsdl, new ProxyTest(sServiceWsdl, sContract));
                    }
                }
            }

            return ((ProxyTest)hashFactory[sServiceWsdl]).getProxy();
        }

        public static bool isProxyExists(String sServiceWsdl, String sContract)
        {
            lock (syncRoot)
            {
                return hashFactory[sServiceWsdl] == null ? false : true;
            }
        }
    }
}

有ProxyTest的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WcfSamples.DynamicProxy;

namespace WS_Generic
{
    public class ProxyTest
    {
        private DateTime instanceCreation;
        private String sServiceWsdl;
        private String sContract;
        private DynamicProxyFactory factory;
        private volatile DynamicProxy proxy;

        public ProxyTest(String sServiceWsdl, String sContract)
        {
            instanceCreation = DateTime.Now;
            this.sServiceWsdl = sServiceWsdl;
            this.sContract = sContract;
            this.factory = new DynamicProxyFactory(this.sServiceWsdl);
            this.proxy = factory.CreateProxy(this.sContract);
        }

        public DynamicProxy getProxy()
        {
            return proxy;
        }

        public TimeSpan getTimeFromCreation()
        {
            return DateTime.Now.Subtract(instanceCreation);
        }
    }
}

问题是webservice似乎在每次调用后重置FactoryTest的静态状态。因此,每次调用webservice时,我的哈希表都是空的,工厂会创建一个新实例。

如果有人在WCF webservice中找到不同线程之间的共享数据问题(并找到解决方案),请提前感谢给我一些提示:)

PS:对不起我的英语,那不是我的母语

1 个答案:

答案 0 :(得分:0)

如果将数据存储在静态变量中,WCF本身不会影响它们的清除。问题必须在其他地方(应用程序重启,应用程序域重新创建等)。

顺便说一下。此解决方案的使用非常有限,因为不应使用长生活共享代理,并且在许多情况下它可能导致意外行为。它可能仅适用于使用basicHttpBinding的服务。