2011-02-11 4 views
19

Kısa bir süre önce, WCF'nin servis tarafındaki zaman aşımı işlemlerini desteklemediğini keşfettik (not, hizmeti, tarafı, istemci tarafı değil). İstemci belirtilen süreden sonra bağlantısını keserken, bizim testlerimiz netNamedPipeBinding, netTcpBinding ve basicHttpBinding için belirttiğimiz zamanaşımının, hizmet işleminin başlatıldıktan sonra durmasına neden olacağını gösterdi.Neden WCF hizmet tarafı zaman aşımlarını desteklemiyor?

<bindings> 
    <netNamedPipeBinding> 
    <binding name="TestServiceBindingConfigurationNamedPipe" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </netNamedPipeBinding> 
    <netTcpBinding> 
    <binding name="TestServiceBindingConfigurationTcp" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </netTcpBinding> 
    <basicHttpBinding> 
    <binding name="TestServiceBindingConfigurationBasicHttp" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </basicHttpBinding> 
</bindings> 

Bizim testi hizmeti uygulaması aşağıdaki gibidir: Aşağıda denedik spesifik bağlanma yapılandırmalarıdır

public class TestServiceImpl : ITestService 
{ 
    public TestResult TestIt(TestArgs args) 
    { 
     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     // this is a contrived example, but it shows that WCF never stops this thread 
     while (true) 
     { 
      Console.WriteLine("{0}> I'm running forever...", stopwatch.Elapsed); 
     } 

     return new TestResult {Result = "Args were " + args.Args}; 
    } 
} 

netNamedPipeBinding ve NetTcpBinding kullanarak, bizim istemci uygulaması 5 saniye sonra zaman aşımına, ama hizmet mi süresiz koşmaya devam et.

Bu benim sorum (ler) i getirir - Bu bir hata mı? WCF'nin beklenenden daha uzun süre çalıştığı durumlarda hizmet sunma istememesinin belirli bir nedeni var mı? Benim açımdan

, bu potansiyel olumsuz konulardan bazıları şunlardır: Sonsuza çalışır hizmetinizdedir kötü kod var ve eğer servis örneklerinin

  1. varsayılan sınırı nedenle 10'dur 10 kere vur, hizmetin tamamen kapanacak; yeni bağlantı kabul edilmez.
  2. Hizmetlerin sonsuza kadar devam ettiği konusunda herhangi bir görünürlük yoktur - özel günlüğe kaydetme süresinin uzunluğu veya muhtemelen performans sayaçlarının kullanılması
  3. Hizmet çağrısında kullanılan tüm kaynaklar süresiz olarak tutulabilir (SQL satırı, sayfa, ve zaman aşımı için başka mekanizmalar yoksa, örneğin tablo kilitleri.

cevap

8

Sonsuza dek çalışan kötü bir kodunuz varsa, zaman aşımını yapmak yalnızca işleri daha da kötüleştirebilir. Mümkün olduğunda hatalı kodu düzeltin! Bu tür durumlar hakkında Eric Lippert'in makalesine bakın, Careful with that axe.

Eğer bu geliştirme aşamasındaysa, servis uygulamanızın içindenumaralı telefonu arayarak bir System.Threading.Timer kurmayı deneyebilirsiniz. Ancak, dönmeden önce zamanlayıcıyı iyice devre dışı bıraktığınızdan emin olun - bu yaklaşım, hizmet çağrısının geldiği iş parçacığına sahip olmamasına, ThreadAbortException'un garip davranışına sahip olmamasına bağlı olarak, eşzamanlılık sorunlarının bir karışımı nedeniyle delil hatayla karşılaşabilir ve Eric'in yabani otlarda yok olan körü körüne sonlandırma kodunu açıkladığı konular.

+0

İstediğimiz şey, sonsuza kadar koşan kötü kodun görünürlüğüdür. Bunu iptal etmeyi tercih edip, daha sonra düzeltmek için kötü bir kodumuz olduğunu bize söyleyebilmek için görünebilirlik olmadan CPU'yu yiyebileceklerinden daha fazla bir TimeoutException almayı tercih ediyoruz. –

+1

Evet, çok uzun süren kodlardan kurtulmak mantıklı. Peki ya sonsuza dek koşmasını beklemediğiniz zaman?Hizmetin hala devam ettiğini ve tüm müşterilerin uzun zaman bağlantısının kesildiği zamanki durumu nasıl anlayacaksınız? – Jab

+0

Hizmet iş parçacığını iptal etmek için bir zamanlayıcıya sahip olmakla ilgili olarak, bu, tam olarak uyguladığımız şeyi sonlandırdığımız şeydir. Soruyu sormamın bir sebebi, bu kodu kendim yazmaktan rahatsız olduğum için çünkü "dediğim gibi," delice hataya eğilimli "diye düşünüyorum. Bir yerde bir konfigürasyon hattını kaçırdığımı umuyorum. –

0

Ne hakkında:

<system.web> 
    <httpRuntime executionTimeout="inSeconds"/> 
</system.web> 
+2

Bu, kendi kendini barındıran hizmetler için işe yaramazdı, değil mi? –

2

bu sorunu kendim fark ettik ... Onların hizmet tarafı operasyonu içermez neden iyi bir neden düşünemiyorum parçası olarak zaman aşımı platformudur.