Как делиться данными в веб-сервисе WCF - PullRequest
0 голосов
/ 22 ноября 2011

Для динамического вызова веб-сервисов я использую WCF Dynamic Proxy от Microsoft

Если я правильно понял, как он работает, код загружает wsdl и компилируется в системный класс, чтобыиспользовать удаленный веб-сервис.Я поместил этот код в «универсальный веб-сервис».Его цель - вызвать любой веб-сервис с запросом в параметре и ответить на его ответ.

Но возникает проблема: каждый запрос к этому «универсальному веб-сервису» вызывает новую компиляцию прокси, ииспользовать время и ресурсы сервера.

Моя цель - сохранить экземпляр каждого прокси в течение промежутков времени и обновить экземпляр, когда этот круг достигнут.

После нескольких часов поиска в GoogleЯ нашел два способа:

  • Использовать мой веб-сервис WCF «по сеансам», но я не нашел ни одного учебника, который объясняет, как легко создать слой сеанса
  • Использовать синглтон вЧтобы сохранить мои данные и связать их со всеми экземплярами веб-сервиса

Я исключаю первое решение, потому что не знаю, как это сделать.Поэтому я решил использовать второй способ.

Вот моя реализация:

  • FactoryTest - это синглтон, содержащий хэш-таблицу с экземплярами
  • ProxyTest - это класс, которыйсодержит информацию о каждом экземпляре удаленных веб-сервисов

Есть код 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);
        }
    }
}

Проблема в том, что веб-сервис сбрасывает статическое состояние FactoryTest после каждого вызова.Поэтому каждый раз, когда я вызывал веб-сервис, моя хеш-таблица пуста, и фабрика создает новый экземпляр.

Если у кого-то уже была проблема совместного использования данных между разными потоками в веб-сервисе WCF (и нашел решение), спасибо взаранее, чтобы дать мне несколько советов:)

PS: Извините за мой английский, это не мой родной язык

1 Ответ

0 голосов
/ 22 ноября 2011

Если вы храните данные в статической переменной, сама WCF не повлияет на их очистку. Проблема должна быть в другом месте (перезапуск приложения, восстановление домена приложения и т. Д.).

Btw. Это решение имеет очень ограниченное использование, потому что долгоживущие общие прокси не должны использоваться, и во многих случаях это может привести к неожиданному поведению. Возможно, он может работать только для служб, использующих basicHttpBinding.

...