SORU
22 Temmuz 2015, ÇARŞAMBA


Visual Studio hata ayıklayıcı Sağlar bir geçersiz kılma değerlendirme dur ne yapar?

Ortam: Visual Studio 2015 RTM. (Eski sürümleri denemedim.)

Son zamanlarda, bazı hata ayıklama benim Noda Time kod ve fark ettim o zaman bende bir yerel değişken tipi NodaTime.Instant (bir merkez struct tür Noda Zaman), "Halk" ve "İzlemek" windows yok görünmesini çağrı ToString() geçersiz kılar. Eğer ToString() açıkça izle pencere ararsam uygun temsilini görüyorum, ama aksi takdirde sadece bakın:

variableName       {NodaTime.Instant}

çok yararlı değil.

Eğer yükleyiciyi sabit bir dize döndürmek için ben değiştirmek, dizeşurası kesin ki, bu sadece "kendi" devlet. normal kullanmak istemeyen almak mümkün değil o yüzden hata olarak gösterilir.

Bu yerel olarak üretmek için küçük bir demo uygulama karar verdim ve buraya geldim. (Not Bu bir erken sürümü bu yazı, DemoStruct bir sınıf ve DemoClass hiç var olmamış hiç - benim hatam, ama bu açıklar bazı yorumlar ki bak şimdi garip...)

using System;
using System.Diagnostics;
using System.Threading;

public struct DemoStruct
{
    public string Name { get; }

    public DemoStruct(string name)
    {
        Name = name;
    }

    public override string ToString()
    {
        Thread.Sleep(1000); // Vary this to see different results
        return $"Struct: {Name}";
    }
}

public class DemoClass
{
    public string Name { get; }

    public DemoClass(string name)
    {
        Name = name;
    }

    public override string ToString()
    {
        Thread.Sleep(1000); // Vary this to see different results
        return $"Class: {Name}";
    }
}

public class Program
{
    static void Main()
    {
        var demoClass = new DemoClass("Foo");
        var demoStruct = new DemoStruct("Bar");
        Debugger.Break();
    }
}

Hata ayıklayıcı, şimdi anlıyorum:

demoClass    {DemoClass}
demoStruct   {Struct: Bar}

Ancak, eğer Thread.Sleep İ azaltmak 1 900ms, yine kısa bir duraklama var ikinci Ara ama sonra ben değer olarak Class: Foo bkz. Thread.Sleep çağrı her zaman düzgün görünen bir şey DemoStruct.ToString(), ne kadar önemli görünmüyor ve hata ayıklayıcı uyku tamamlardı önce değerini görüntüler. (Thread.Sleep devre dışı olarak.)

Şimdi Instant.ToString() Noda Zaman mı adil bir miktar iş, ama kesinlikle gerek yok tüm ikinci - yani muhtemelen orada daha fazla koşul bu neden hata PES değerlendirilmesi ToString() Ara. Ve tabii ki bir yapı zaten.

Sınırı bir yığın şey olup olmadığını görmek için recursing denedim, ama öyle olmadığı görülüyor.

Nasıl tam Instant.ToString() değerlendirme dan VS duruyor ne iş yapabilirim? Aşağıda, DebuggerDisplayAttribute görünür ama bilmeden yardım etmeye kaydettinedenHiç ihtiyacım olduğunda ve bilmiyorum ne zaman tamamen emin olacağım.

Güncelleme

Eğer DebuggerDisplayAttribute, kullanırsam işler değişir:

// For the sample code in the question...
[DebuggerDisplay("{ToString()}")]
public class DemoClass

verir bana

demoClass      Evaluation timed out

Noda zamanında başvurduğumda ise:

[DebuggerDisplay("{ToString()}")]
public struct Instant

basit bir test uygulaması bana doğru sonucu gösterir:

instant    "1970-01-01T00:00:00Z"

Bu yüzden muhtemelen sorun Noda Zaman DebuggerDisplayAttribute bazı durumduryokzaman aşımı zorla değil ama içinden bile güç. (Bu Instant.ToString kolayca bir zaman aşımı önlemek için yeterince hızlı benim beklentim doğrultusunda olacaktır.)

Buolabilirolması yeterince iyi bir çözüm ama istiyorum yine de bilmek neler olup değiştirebilirim kodu sadece önlemek zorunda koymak özniteliği tüm çeşitli değer türleri Noda Zaman.

Daha da meraklandım şimdi

Hata ayıklayıcı, kafa karıştırıcı ne olursa olsun sadece bazen kafam karışıyor. Diyelim ki bir sınıf oluşturuntutarbir 36 ** ToString() kendi yöntemini kullanır:

using NodaTime;
using System.Diagnostics;

public class InstantWrapper
{
    private readonly Instant instant;

    public InstantWrapper(Instant instant)
    {
        this.instant = instant;
    }

    public override string ToString() => instant.ToString();
}

public class Program
{
    static void Main()
    {
        var instant = NodaConstants.UnixEpoch;
        var wrapper = new InstantWrapper(instant);

        Debugger.Break();
    }
}

Şimdi görüyorum sonunda

instant    {NodaTime.Instant}
wrapper    {1970-01-01T00:00:00Z}

Eğer InstantWrapper bir yapı olması değiştirirsem ancak, yorum Eren teklifi doğrultusunda, anlıyorum:

instant    {NodaTime.Instant}
wrapper    {InstantWrapper}

Bu yüzdenolabilirToString başka bir yöntemi tarafından çağrılır yeter... bir sınıf içinde Instant.ToString() - değerlendirmek. Sınıf/yapı kısmı ihtiyacı olmayan değişken görüntülenen, Türüne göre çok önemli olmalı sonuç almak amacıyla yürütülecek.

Bu başka bir örnek olarak, eğer kullanırsak:

object boxed = NodaConstants.UnixEpoch;

... gayet iyi çalışıyor o zaman, doğru değeri görüntüleme. Bana karışık renkli.

CEVAP
22 Temmuz 2015, ÇARŞAMBA


Visual Studio 2015 ile bilinen böcek/tasarım sınırlaması çalışıyor ve yapı tipleri Olabilirdi diyorsun. Bu da System.DateTimeSpan ile uğraşırken görülebilir. System.DateTimeSpan.ToString() Visual Studio ile değerlendirme yapmalıdır 2013, ama her zaman, 2015'te çalışmıyor.

Eğer düşük seviye detayları ile ilgilenen varsa, burada neler var:

ToString hata ayıklayıcı olarak bilinen şeyi yapar değerlendirmek için "fonksiyon değerlendirme". Büyük ölçüde basitleştirilmiş açısından, hata ayıklayıcı, askıya tüm konuları işlemi dışında geçerli iş parçacığı, değişiklikler kapsamında geçerli iş parçacığı için ToString işlevi, ayarlar gizli bir guard kesme, sonra izin süreci devam ediyor. Guard kesme noktasına gelindiğinde, hata ayıklayıcı önceki durumuna geri yükler süreç ve işlevin dönüş değeri pencere doldurmak için kullanılır.

Lambda ifadeleri destekleyen, tamamen Visual Studio 2015 CLR İfade Değerlendiricisi yeniden yazmak zorunda kaldık. Yüksek bir düzeyde, uygulanması

  1. Roslyn ifadeler/yerel değişkenler değerleri çeşitli denetleme windows görüntülenecek almak için MSIL kod oluşturur.
  2. Hata ayıklayıcı, IL sonucu elde etmek için yorumlar.
  3. "Talimatları, hata ayıklayıcı yürüten bir çağrı varsa, orada yukarıda açıklandığı gibi işlev değerlendirmesi.
  4. Hata ayıklayıcı/roslyn, bu sonuç ve biçimleri alır ağaç gibi kullanıcıya gösterilen görüntüleyin.

IL yürütülmesi nedeniyle, hata ayıklayıcı her zaman "gerçek" ve "sahte" değerleri. karmaşık bir karışımı ile uğraşıyor Gerçek değerleri aslında işlem ayıklanacak var. Sahte değerler, yalnızca hata ayıklama süreci var. Uygun yapı semantiği uygulamak için, hata ayıklayıcı her zaman IL için yapı değeri zorlandığında değer bir kopyasını yığın yapmak gerekiyor. Kopyalanan değeri artık bir "değer ve şimdi sadece hata ayıklama süreci var." Eğer biz daha sonra değeri süreç içinde yok çünkü fonksiyon değerlendirme yapamayız gerçekleştirmek için gerekiyorsa anlamına gelir. Deneyin ve ToString yöntemi yürütme taklit etmeliyiz değerini almak için. Bazı şeyleri taklit ederken, birçok sınırlamalar vardır. Örneğin, yerel kod taklit edemeyiz ve "temsilci değerleri veya aramaları yansıma değerleri. gerçek çağrıları idam edemeyiz

Aklınızda ile, burada gördüğünüz farklı davranışlara sebep oluyor:

  1. Hata ayıklayıcı NodaTime.Instant.ToString - ^ değerlendirme değil . Bu yapı tipi ve Olabilirdi uygulanması olamaz çünkü yukarıda açıklandığı gibi hata ayıklayıcı tarafından taklit edilebilir.
  2. Thread.Sleep ToString tarafından çağrıldığında sıfır zaman alacak gibi görünüyor - ^yapı . Bu emülatörü ToStringyürütülüyor olmasıdır. İplik.Uyku doğal bir yöntemdir, ama öykünücüsü farkında bu sadece bir çağrı yok sayar. Bu deneyin ve bir değer elde etmek için yapıyoruz kullanıcıya göstermek için. Bir gecikme bu durumda yardımcı olmaz.
  3. DisplayAttibute("ToString()") çalışır. ->Bu kafa karıştırıcı. Tek ToString ve örtülü çağırma arasındaki fark DebuggerDisplay *58 örtülü*zaman aşımı olur değerlendirme için ToString tüm örtülü değerlendirmeler devre dışı bırakır bir sonraki hata ayıklama oturumu kadar yazın. Bu gözlem olabilir davranış.

Tasarım açısından sorun/hata, Visual Studio bir sonraki sürümünde adres için planladığımız bir şey.

Umarım bu işler düzelir. Eğer daha fazla sorunuz varsa bana bildirin. :-)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • RawBrahs

    RawBrahs

    28 Aralık 2010
  • Virtual Riot

    Virtual Riot

    19 Mayıs 2011
  • Yo Mama

    Yo Mama

    18 EYLÜL 2005