2016-05-01 14 views
0

Ich habe eine App, die eine Datei lädt, die wie key:value formatiert ist, und fügt sie dann zu Dictionary. Das funktioniert gut mit kleinen Dateien, aber wenn ich versuche, eine Datei zu laden, die 65.000 Zeilen hat, wird es nicht funktionieren und wirft Index was outside the bounds of the array. auf Dictionary.TryAdd().Index war außerhalb der Grenzen des Arrays auf einem Wörterbuch

Ich kompiliere meine App für 64-Bit-Architekturen und ich setzte auch die <gcAllowVeryLargeObjects enabled="true" /> in der app.config.

private void LoadFile() 
{ 
    ConcurrentDictionary<string, string> Dict = new ConcurrentDictionary<string, string>(); 

    OpenFileDialog dlgFile = new OpenFileDialog(); 
    dlgFile.Filter = "All Files (*.*)|*.*"; 
    dlgFile.FilterIndex = 1; 

    if (dlgFile.ShowDialog() == DialogResult.OK) 
    { 
     foreach (string line in File.ReadLines(dlgFile.FileName)) 
     { 
      // Index was outside the bounds of the array. 
      Dict.TryAdd(line.Split(':')[0], line.Split(':')[1]); 
     } 
    } 
} 
+3

Ich denke, das Problem ist mit der Array-Indizierung. Sind Sie sicher, dass alle "Zeilen" das erforderliche Format haben, aka kann durch ":" getrennt werden? –

+0

@Daniel Leszen Ja, sie sind –

+0

Ich würde vorschlagen, dass Sie noch einmal überprüfen. Wenn die Ausnahme ausgelöst wird, klicken Sie mit der Maus über "line", um zu sehen, welcher Wert fehlschlägt. Die Wahrscheinlichkeit ist, dass es nicht ':' enthält - wenn Sie sicher sind, dass es alle tun, dann ist es manchmal die letzte (leere) Zeile. –

Antwort

0

Dies ist fast sicher, weil eine Ihrer Zeilen : nicht enthält, so dass die Indexierung in das resultierende Split string Array fehlschlagen wird, da es nicht 2 Teile dazu gibt.

Sie Linien überspringen könnte, die zwei Teile, wie nicht so haben:

foreach (string line in File.ReadLines(dlgFile.FileName)) 
{ 
    var parts = line.Split(':'); 

    if (parts.Length == 2) 
    { 
     var key = parts[0]; 
     var value = parts[1]; 
     Dict.TryAdd(key, value); 
    } 
    else 
    { 
     // log that line was ignored 
    } 
} 

Als beiseite, gibt es keine Notwendigkeit ConcurrentDictionary zu verwenden, wenn Sie den gleichzeitigen Zugriff haben. Möglicherweise befindet sich an anderer Stelle in Ihrer Anwendung, aber es gibt keine in dem Code, den Sie angezeigt haben.

+0

Wie ich in der anderen Antwort kommentiert habe, habe ich jetzt ein anderes Problem. 'Die CLR konnte 60 Sekunden lang nicht vom COM-Kontext 0xb40a9278 in den COM-Kontext 0xb40a93a0 übergehen. ' –

+0

Hit weiter und warten weiter. Es ist wahrscheinlich, dass dies nur eine lange Zeit dauert, was ein Argument dafür sein kann, dies nicht auf dem UI-Thread zu tun. –

+0

'BackgroundWorker' vielleicht? –

0

Bitte, versuchen Sie die foreach Körper auf die folgende Codesegment ändern:

 var parts = line.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); 
     if (parts.Length > 1) 
     { 
      Dict.TryAdd(parts[0], parts[1]); 
     } 
     else 
     { 
      // ERROR logging 
     } 

Entfernen leere Einträge nicht neccesary ist jedoch macht es sicher, dass Sie nicht mit leeren Schlüssel oder Werte zum Wörterbuch hinzufügen würde. Ich würde auch vorschlagen, um sicherzustellen, dass das Wörterbuch nicht den gleichen Schlüssel enthält.

+0

Das löste mein Problem aber führte zu einem anderen. 'Die CLR konnte 60 Sekunden lang nicht vom COM-Kontext 0xb40a9278 in den COM-Kontext 0xb40a93a0 übergehen. ' –

Verwandte Themen