Aracılığıyla paylaş


Başlatmayı Örneklendirme

Başlatma örneği, bir nesneyi etkinleştirerek ve devre dışı bırakarak başlatmayı özelleştiren bir arabirim tanımlayarak HavuzIObjectControl. İstemci, nesnesini havuza döndüren ve nesneyi havuza döndürmeyen yöntemleri çağırır.

Not

Bu örnek için kurulum yordamı ve derleme yönergeleri bu konunun sonunda yer alır.

Genişletilebilirlik Noktaları

Windows Communication Foundation (WCF) uzantısı oluşturmanın ilk adımı, kullanılacak genişletilebilirlik noktasına karar vermektir. WCF'de EndpointDispatcher terimi, gelen iletileri kullanıcının hizmetinde yöntem çağrılarına dönüştürmekten ve dönüş değerlerini bu yöntemden giden iletiye dönüştürmekten sorumlu bir çalışma zamanı bileşenini ifade eder. WCF hizmeti her uç nokta için bir EndpointDispatcher oluşturur.

EndpointDispatcher, sınıfını kullanarak EndpointDispatcher uç nokta kapsamı (hizmet tarafından alınan veya gönderilen tüm iletiler için) genişletilebilirlik sunar. Bu sınıf, EndpointDispatcher'ın davranışını denetleen çeşitli özellikleri özelleştirmenize olanak tanır. Bu örnek, hizmet sınıfının örneklerini sağlayan nesneye işaret eden özelliğe odaklanır InstanceProvider .

IInstanceProvider

WCF'de EndpointDispatcher, arabirimini uygulayan IInstanceProvider bir örnek sağlayıcısı kullanarak bir hizmet sınıfının örneklerini oluşturur. Bu arabirimin yalnızca iki yöntemi vardır:

Nesne Havuzu

sınıfı, ObjectPoolInstanceProvider nesne havuzu için uygulamayı içerir. Bu sınıf, hizmet modeli katmanıyla etkileşime geçmek için arabirimini uygular IInstanceProvider . EndpointDispatcher yeni bir örnek oluşturmak yerine yöntemini çağırdığında GetInstance , özel uygulama bellek içi havuzda var olan bir nesneyi arar. Varsa, döndürülür. Aksi takdirde, ObjectPoolInstanceProvider özelliğin ActiveObjectsCount (havuzdan döndürülen nesne sayısı) havuz boyutu üst sınırına ulaşıp ulaşmadığını denetler. Aksi takdirde, yeni bir örnek oluşturulur ve çağırana döndürülür ve ActiveObjectsCount daha sonra artırılır. Aksi takdirde, nesne oluşturma isteği yapılandırılmış bir süre için kuyruğa alınır. uygulaması GetObjectFromThePool aşağıdaki örnek kodda gösterilmiştir.

private object GetObjectFromThePool()
{
    bool didNotTimeout =
       availableCount.WaitOne(creationTimeout, true);
    if(didNotTimeout)
    {
         object obj = null;
         lock (poolLock)
        {
             if (pool.Count != 0)
             {
                   obj = pool.Pop();
                   activeObjectsCount++;
             }
             else if (pool.Count == 0)
             {
                   if (activeObjectsCount < maxPoolSize)
                   {
                        obj = CreateNewPoolObject();
                        activeObjectsCount++;

                        #if (DEBUG)
                        WritePoolMessage(
                             ResourceHelper.GetString("MsgNewObject"));
                       #endif
                   }
            }
           idleTimer.Stop();
      }
     // Call the Activate method if possible.
    if (obj is IObjectControl)
   {
         ((IObjectControl)obj).Activate();
   }
   return obj;
}
throw new TimeoutException(
ResourceHelper.GetString("ExObjectCreationTimeout"));
}

Özel ReleaseInstance uygulama, serbest bırakılmış örneği havuza geri ekler ve değeri geri ActiveObjectsCount alır. EndpointDispatcher bu yöntemleri farklı iş parçacıklarından çağırabilir ve bu nedenle sınıftaki sınıf düzeyi üyelerine ObjectPoolInstanceProvider eşitlenmiş erişim gereklidir.

public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
    lock (poolLock)
    {
        // Check whether the object can be pooled.
        // Call the Deactivate method if possible.
        if (instance is IObjectControl)
        {
            IObjectControl objectControl = (IObjectControl)instance;
            objectControl.Deactivate();

            if (objectControl.CanBePooled)
            {
                pool.Push(instance);

                #if(DEBUG)
                WritePoolMessage(
                    ResourceHelper.GetString("MsgObjectPooled"));
                #endif
            }
            else
            {
                #if(DEBUG)
                WritePoolMessage(
                    ResourceHelper.GetString("MsgObjectWasNotPooled"));
                #endif
            }
        }
        else
        {
            pool.Push(instance);

            #if(DEBUG)
            WritePoolMessage(
                ResourceHelper.GetString("MsgObjectPooled"));
            #endif
        }

        activeObjectsCount--;

        if (activeObjectsCount == 0)
        {
            idleTimer.Start();
        }
    }

    availableCount.Release(1);
}

ReleaseInstance yöntemi bir temizleme başlatma özelliği sağlar. Normalde havuz, havuzun ömrü boyunca en az sayıda nesne tutar. Ancak, yapılandırmada belirtilen üst sınıra ulaşmak için havuzda ek nesneler oluşturulmasını gerektiren aşırı kullanım dönemleri olabilir. Sonunda havuz daha az etkin hale geldiğinde bu fazlalık nesneler ek yük haline gelebilir. Bu nedenle, sıfıra activeObjectsCount ulaştığında, bir temizleme döngüsünü tetikleyen ve gerçekleştiren bir boşta zamanlayıcı başlatılır.

if (activeObjectsCount == 0)
{
    idleTimer.Start();
}

ServiceModel katman uzantıları aşağıdaki davranışlar kullanılarak bağlanır:

  • Hizmet Davranışları: Bunlar hizmet çalışma zamanının tamamını özelleştirmeye olanak tanır.

  • Uç Nokta Davranışları: Bunlar EndpointDispatcher dahil olmak üzere belirli bir hizmet uç noktasının özelleştirilmesine olanak sağlar.

  • Sözleşme Davranışları: Bunlar, sırasıyla istemcide veya hizmette ya da ClientRuntimeDispatchRuntime sınıflarında özelleştirmeye olanak sağlar.

  • İşlem Davranışları: Bunlar sırasıyla istemcide veya hizmette ya da ClientOperationDispatchOperation sınıflarında özelleştirmeye olanak tanır.

Nesne havuzu uzantısının amacı doğrultusunda bir uç nokta davranışı veya hizmet davranışı oluşturulabilir. Bu örnekte, hizmetin her uç noktasına nesne havuzu oluşturma özelliğini uygulayan bir hizmet davranışı kullanırız. Hizmet davranışları, arabirimi uygulanarak IServiceBehavior oluşturulur. ServiceModel'i özel davranışlardan haberdar etmenin çeşitli yolları vardır:

  • Özel öznitelik kullanma.

  • Bunu hizmet açıklamasının davranış koleksiyonuna kesin olarak ekleme.

  • Yapılandırma dosyasını genişletme.

Bu örnek özel bir öznitelik kullanır. ServiceHost oluşturulduğunda, hizmetin tür tanımında kullanılan öznitelikleri inceler ve kullanılabilir davranışları hizmet açıklamasının davranış koleksiyonuna ekler.

Arabirimin IServiceBehavior üç yöntemi vardır: Validate,AddBindingParameters, ve .ApplyDispatchBehavior Bu yöntemler, başlatıldığında WCF ServiceHost tarafından çağrılır. IServiceBehavior.Validate önce çağrılır; hizmetin tutarsızlıklar açısından denetlenmesini sağlar. IServiceBehavior.AddBindingParameters sonraki olarak adlandırılır; bu yöntem yalnızca çok gelişmiş senaryolarda gereklidir. IServiceBehavior.ApplyDispatchBehavior son olarak adlandırılır ve çalışma zamanını yapılandırmakla sorumludur. aşağıdaki parametreler içine IServiceBehavior.ApplyDispatchBehaviorgeçirilir:

  • Description: Bu parametre, hizmetin tamamı için hizmet açıklamasını sağlar. Bu, hizmetin uç noktaları, sözleşmeleri, bağlamaları ve hizmetle ilişkili diğer verileri hakkındaki açıklama verilerini incelemek için kullanılabilir.

  • ServiceHostBase: Bu parametre şu anda başlatılmakta ServiceHostBase olan parametresini sağlar.

Özel IServiceBehavior uygulamada, yeni bir örneği ObjectPoolInstanceProvider oluşturulur ve her InstanceProvider biri öğesine eklenen özelliğine EndpointDispatcheratanırServiceHostBase.

public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
    if (enabled)
    {
        // Create an instance of the ObjectPoolInstanceProvider.
        instanceProvider = new ObjectPoolInstanceProvider(description.ServiceType,
        maxPoolSize, minPoolSize, creationTimeout);

        // Assign our instance provider to Dispatch behavior in each
        // endpoint.
        foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
        {
             ChannelDispatcher cd = cdb as ChannelDispatcher;
             if (cd != null)
             {
                 foreach (EndpointDispatcher ed in cd.Endpoints)
                 {
                        ed.DispatchRuntime.InstanceProvider = instanceProvider;
                 }
             }
         }
     }
}

Bir IServiceBehavior uygulamaya ek olarak, sınıfın ObjectPoolingAttribute öznitelik bağımsız değişkenlerini kullanarak nesne havuzunu özelleştirmek için birkaç üyesi vardır. Bu üyeler, .NET Enterprise Services tarafından sağlanan nesne havuzu özelliği kümesiyle eşleşmesi için , MaxSizeve MinSizeEnablediçerirCreationTimeout.

Nesne havuzu oluşturma davranışı artık yeni oluşturulan özel ObjectPooling öznitelikle hizmet uygulamasına ek açıklama eklenerek bir WCF hizmetine eklenebilir.

[ObjectPooling(MaxSize=1024, MinSize=10, CreationTimeout=30000]
public class PoolService : IPoolService
{
  // …
}

Kanca Etkinleştirme ve Devre Dışı Bırakma

Nesne havuzu oluşturmanın birincil amacı, nispeten pahalı oluşturma ve başlatma ile kısa ömürlü nesneleri iyileştirmektir. Bu nedenle, düzgün kullanıldığında uygulamaya önemli bir performans artışı sağlayabilir. Nesnesi havuzdan döndürülür çünkü oluşturucu yalnızca bir kez çağrılır. Ancak, bazı uygulamalar tek bir bağlam sırasında kullanılan kaynakları başlatabilmeleri ve temizleyebilmeleri için bir denetim düzeyi gerektirir. Örneğin, bir hesaplama kümesi için kullanılan bir nesne, sonraki hesaplamayı işlemeden önce özel alanlarını sıfırlayabilir. Kurumsal Hizmetler, nesne geliştiricisinin temel sınıftan ve Activate yöntemlerini geçersiz kılıp geçersiz kmasına Deactivate izin vererek bu tür bağlama özgü başlatmayı ServicedComponent etkinleştirdi.

Nesne havuzu, nesnesini havuzdan Activate döndürmeden hemen önce yöntemini çağırır. Deactivate , nesne havuza geri döndüğünde çağrılır. ServicedComponent Temel sınıf ayrıca adlı bir boolean özelliğe sahiptir ve bu özellikCanBePooled, nesnenin daha fazla havuza alınıp alınamayacağını havuza bildirmek için kullanılabilir.

Bu işlevi taklit etmek için örnek, yukarıda belirtilen üyeleri içeren bir ortak arabirim (IObjectControl) bildirir. Daha sonra bu arabirim, bağlama özgü başlatmayı sağlamak amacıyla hizmet sınıfları tarafından uygulanır. Bu IInstanceProvider gereksinimleri karşılamak için uygulamanın değiştirilmesi gerekir. Şimdi, yöntemini çağırarak GetInstance bir nesneyi her aldığınızda, nesnenin uygulanıp uygulanmadığını denetlemeniz gerekir Eğer uygularsa IObjectControl. , yöntemini uygun şekilde çağırmanız Activate gerekir.

if (obj is IObjectControl)
{
    ((IObjectControl)obj).Activate();
}

Bir nesneyi havuza döndürürken, nesneyi havuza geri eklemeden önce özellik için CanBePooled bir denetim gerekir.

if (instance is IObjectControl)
{
    IObjectControl objectControl = (IObjectControl)instance;
    objectControl.Deactivate();
    if (objectControl.CanBePooled)
    {
       pool.Push(instance);
    }
}

Hizmet geliştiricisi bir nesnenin havuza alınıp alınamayacağına karar verebileceğinden, belirli bir anda havuzdaki nesne sayısı minimum boyutun altına inebilir. Bu nedenle, nesne sayısının en düşük düzeyin altına inip inmediğini denetlemeniz ve temizleme yordamında gerekli başlatmayı gerçekleştirmeniz gerekir.

// Remove the surplus objects.
if (pool.Count > minPoolSize)
{
  // Clean the surplus objects.
}
else if (pool.Count < minPoolSize)
{
  // Reinitialize the missing objects.
  while(pool.Count != minPoolSize)
  {
    pool.Push(CreateNewPoolObject());
  }
}

Örneği çalıştırdığınızda, işlem istekleri ve yanıtları hem hizmet hem de istemci konsol pencerelerinde görüntülenir. Hizmeti ve istemciyi kapatmak için her konsol penceresinde Enter tuşuna basın.

Örneği ayarlamak, derlemek ve çalıştırmak için

  1. Windows Communication Foundation Örnekleri için Tek Seferlik Kurulum Yordamı'nı gerçekleştirdiğinizden emin olun.

  2. Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.

  3. Örneği tek veya makineler arası bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.