2011-11-16 5 views
6

Aşağıdakileri göz önünde bulundurun:Neden her farklı dinamik çağrı iki istisna ile sonuçlanır ve bunlar bastırılabilir?

using System; 
using System.Dynamic; 
using System.Linq; 

namespace DynamicObjectTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      dynamic dyn = new TestDynamic(); 
      Console.ReadKey(); 

      foreach (var i in Enumerable.Range(0, 100)) 
      { 
       Console.WriteLine(dyn.Foo()); 
       Console.WriteLine(dyn.Bar()); 
      } 

      Console.ReadKey(); 
     } 
    } 

    class TestDynamic : DynamicObject 
    { 
     public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) 
     { 
      if (binder.Name == "Foo") 
      { 
       result = "Bar"; 
       return true; 
      } 
      else if (binder.Name == "Bar") 
      { 
       result = "Foo"; 
       return true; 
      } 

      return base.TryInvokeMember(binder, args, out result); 
     } 
    } 
} 

Bu programı çalıştırırken, RuntimeBinderException tipinde dört istisna atılır. Bunu, tüm atılan özel durumları (Hata Ayıklama/İstisnalar .../Ortak Dil Çalışma Zamanı Özel Durumları Atma onay kutusunu işaretle) veya perfmon kullanarak keserek gözlemleyebilirsiniz:

enter image description here

Artık bu istisnalar açıkça yakalanmış ve işlenmiş dahili olarak TryInvokeMember yöntemi daha sonra çağrılır. Ancak, "istisnai durumlarda istisnai durumlar" mantığına abone olursanız, ağır ele alınmış ve istisnaların uygunsuz kullanımı gözükmektedir. Benim özel örneğim için gerçekten bir sorun değil çünkü aynı üyeler - Foo ve Bar - tekrar tekrar çağırılıyor. Ancak, üyelerin çok daha az statik olduğu diğer senaryolarım var.

Çalışma zamanının herhangi bir istisna atmadan TryInvokeMember'ı çağırmasına yardımcı olacak bir şey var mı?

+1

Yutulması muhtemel bir istisnai durum söz konusu olabilir. Neler olup bittiğini görmek için 'TryInvokeMember' kodunu kaldırabilirsiniz. – Polynomial

+0

Onay kutusunu/atma yaklaşımını kullanırsam, aslında benim için kırılmaz. –

+1

@Polynomial: Sorunun içinde bulunduğuna işaret ettim, ama bu benim sorum değil. –

cevap

2

Sistem, bazen dahili olarak istisnalar atar ve yakalar. Yapabileceğiniz hiçbir şey yoktur (http://connect.microsoft.com/VisualStudio'a geri bildirim göndermek hariç, ancak bunun performansı etkilemesi olası olmadığından hiçbir temel yoktur - DynamicObject ile ilgili diğer masraflar bunu büyük ölçüde aşıyor).

(Eğer tahmin etmem gerekirse, bu dahili bellek "sayfa hatası" donanım istisnası gibi olabilir: sistem istisnanın oluşmasına izin verir, ardından yakalar ve gelecekteki yürütme işleminin başarılı olması için nesneleri bir araya getirir ve bir araya getirir. kodda koşullu bir dallanma gerektirmeyecek şekilde CPU'nun istisna özelliklerini kullandığı için son derece verimli olması gerekir.)

NOT: Orijinal gönderideki kodu denemek için, "Just My Code" u kapatın. "tüm atılan istisnaları kırmak için yapılandırma yanı sıra seçeneği.

+0

'in olası kopyalarının olası bir cevabını verebilir misiniz? Özellikle, DynamicObject ile ilgili diğer giderlerin yanı sıra CPU istisnası özelliklerinin nasıl yürütüldüğünü okumak isterim. Teşekkürler! – defines

İlgili konular