2010-08-16 15 views
28

Bir uygulamada hata ayıklama yaparken, Visual Studio'da özel durum kesildiğinde, her zaman aşağıdaki hatayı alırım. Bu gerçekten beni rahatsız ediyor, çünkü istisnai bir mola ile çalışıyoruz. Komik olan şu ki, devam ettiğim zaman hala çalışıyor (StringCollection yüklendi).ForNotFoundException UygulamaAyarlarBase

İleti geçerli:

dosya veya derleme yüklenemedi 'System.XmlSerializers, Sürüm = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089' ya da bağımlılıklarından biri. Sistem belirtilen dosyayı bulamıyor. İşte

istisna neden olan koddur

[global::System.Configuration.UserScopedSettingAttribute()] 
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
public global::System.Collections.Specialized.StringCollection Mru { 
     get { 
      return ((global::System.Collections.Specialized.StringCollection)(this["Mru"])); 
     } 
     set { 
      this["Mru"] = value; 
     } 
    } 

ben hata gösterir boş bir test uygulama oluşturmak için çalıştı, ancak istisna meydana gelmedi (tasarımcı oluşturulur). Projemiz çok büyük, nedeni bulmak zor. Belki bu sitedeki birisinin bunu nasıl çözeceğine dair bir ipucu vardır.

cevap

51

Bu istisnanın neden atıldığına dair bir açıklama. Bu örnek Windows Forms uygulamasıyla istisnayı yeniden deneyebilirsiniz. StringCollection türünde "Ayar" adlı bir ayar ekleyerek başlayın. Değer sütununda noktalara tıklayın ve birkaç dizge girin. Form sınıf kodunu olun şuna benzer:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
    } 
    protected override void OnFormClosing(FormClosingEventArgs e) { 
     Properties.Settings.Default.Setting[0] = DateTime.Now.ToString(); 
     Properties.Settings.Default.Save(); 
     base.OnFormClosing(e); 
    } 
} 

ayıklama + İstisnalar, CLR istisnalar için atılmış onay kutusunu işaretleyin. Formu çalıştırın ve kapatın, istisna atıldığında hata ayıklayıcı duracaktır. Çağrı yığını üstünde şuna benzer:

mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes 
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes 
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes 
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes 
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes 

Sen StringCollection sınıfı için XML seri hale içeren bir montaj için XmlSerializer sınıfı avcılık görebilirsiniz. LoadGeneratedAssembly yöntemi kaldırıldı sıkıcı bit ile aşağıdaki gibidir:

internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract) 
{ 
    ... 
    AssemblyName parent = GetName(type.Assembly, true); 
    partialName = Compiler.GetTempAssemblyName(parent, defaultNamespace); 
    parent.Name = partialName; 
    parent.CodeBase = null; 
    parent.CultureInfo = CultureInfo.InvariantCulture; 
    try 
    { 
     serializer = Assembly.Load(parent);  // <=== here 
    } 
    catch (Exception exception) 
    { 
     ... 
    } 
    .... 
} 

Ve Compiler.GetTempAssemblyName():

internal static string GetTempAssemblyName(AssemblyName parent, string ns) 
{ 
    return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode()))); 
} 

Bu GetTempAssemblyName bu durumda suçludur. StringCollection sınıfı System.dll derlemesinde yaşar, yöntem "System.XmlSerializers" adını üretir. Bu yöntem, Sgen.exe tarafından oluşturulan kendi sınıflarınız için derlemeyi bulmak üzere tasarlanmıştır. Örnek programınız için WindowsApplication1.XmlSerializers.dll gibi. Ancak StringCollection, .NET Framework'teki bir sınıftır, oluşturduğu derleme adı geçerli değildir. Aslında bir "System.XmlSerializer" yok.dll "çerçeve içinde montaj.

Connect.microsoft.com adresindeki bu davranışla ilgili geri bildirim raporlarının tümü" Tasarım "ile kapatılmıştır. Bu, özgün tasarımcılar istisnayı önleme maliyetinin yüksek olduğu düşünüldü ve istisnayı yakalayın, istisnai olanı yakalayın, istisnai durum gerçekten yakalanır.Gerçek hata mesajını açmak için Debug + Exceptions iletişim kutusunu açtığınız için onu görürsünüz.

Xml serileştirme kodunun farklı davranması burada bir seçenek değil, System.dll grubundaki türleri filtrelemek için yeterince kolay olurdu, ama bu potansiyel olarak hiç bitmeyen bir savaş, bu çerçevede çok daha fazla meclis var.Ancak bir çözüm kendi kullanmak için bunun yerine ayarı kaydetmek için sınıf StringCollection kullanımı.

+0

Detaylı açıklama için teşekkür ederiz. Gelecekte StringCollection kullanmaktan kaçınmaya çalışıyorum. Çok kötü bu "tasarım" dır. – testalino

+0

İşte burada :) – testalino

+0

Yine de mükemmel cevap ... – MoonKnight

1

Çok fazla özel durumla karşılaşıyorsunuz, System.XmlSerializer bu olağan durumu normal çalışmasının bir parçası olarak atar, sınıfın kendisi tarafından yakalanır ve işlenir. Hata ayıklama seçeneklerinizi, yalnızca .net çiftlik çalışma sınıflarında yakalanan ve işlenen istisnaları değil, yalnızca istisnalarınızı yakalamak için değiştirin. Ben sadece iki geçici çözümler sunabilir:

devre dışı bırak bu özel istisna: git ayıklama/İstisnalar, Tür, Ekle 'yi: bu gibi

+1

ick .... gerçekten? – kenny

+1

+1, yup. System.Xml için büyük bir parçadan nefret ediyorum. –

+0

Dediğim gibi, bir test uygulamasında aynı ayarlar özelliği ile İstisna oluşmuyor. Bu yüzden doğru değil, XmlSerializer bu istisnayı her zaman atar. – testalino

6

gerçekten ( XmlSerializer giving FileNotFoundException at constructor da bakınız) normal çalışma parçası gibi görünüyor C++ İstisnalar, Ad: EEFileLoadException (eğer gördüğünüz istisna bu ise), bu istisna için Thrown onay kutusunun işaretini kaldırın.

Ayarlanacak dizenin türünü değiştirin ve ona erişin. öyleyse:

var mru = Settings.Default.Mru.Split('|'); 
Settings.Default.Mru = string.Join("|", mru.ToArray());