Обработка исключений в C # продолжается при ошибке - PullRequest
2 голосов
/ 25 сентября 2008

У меня есть базовое консольное приложение C #, которое построчно читает текстовый файл (в формате CSV) и помещает данные в HashTable. Первый элемент CSV в строке - это ключ (id num), а остальная часть строки - это значение. Однако я обнаружил, что в моем файле импорта есть несколько дубликатов ключей, которых не должно быть. Когда я пытаюсь импортировать файл, приложение выдает ошибки, потому что в HashTable не может быть дубликатов ключей. Я хочу, чтобы моя программа могла обрабатывать эту ошибку, хотя. Когда я сталкиваюсь с дублирующимся ключом, я хотел бы поместить этот ключ в массив и продолжить импорт остальных данных в хеш-таблицу. Как я могу сделать это в C #

Вот мой код:


приватная статическая Hashtable importFile (Hashtable myHashtable, String myFileName) {

        StreamReader sr = new StreamReader(myFileName);
        CSVReader csvReader = new CSVReader();
        ArrayList tempArray = new ArrayList();
        int count = 0;

        while (!sr.EndOfStream)
        {
            String temp = sr.ReadLine();
            if (temp.StartsWith(" "))
            {
                ServMissing.Add(temp);
            }
            else
            {
                tempArray = csvReader.CSVParser(temp);
                Boolean first = true;
                String key = "";
                String value = "";

                foreach (String x in tempArray)
                {
                    if (first)
                    {
                        key = x;
                        first = false;
                    }
                    else
                    {
                        value += x + ",";
                    }
                }
                myHashtable.Add(key, value);
            }
            count++;
        }

        Console.WriteLine("Import Count: " + count);
        return myHashtable;
    }

Ответы [ 7 ]

10 голосов
/ 25 сентября 2008
if (myHashtable.ContainsKey(key))
    duplicates.Add(key);
else
    myHashtable.Add(key, value);
3 голосов
/ 25 сентября 2008

ContainsKey имеет постоянную нагрузку O (1) для каждого элемента, в то время как перехват исключения влечет за собой снижение производительности ПРОСТО дублирующихся элементов.

В большинстве случаев я бы сказал, проверить ключ, но в этом случае лучше ловить исключение.

3 голосов
/ 25 сентября 2008

Лучшее решение - вызвать ContainsKey, чтобы проверить, существует ли ключ, прежде чем добавить его в хеш-таблицу. Исключение из-за такого рода ошибок является падением производительности и не улучшает выполнение программы.

1 голос
/ 25 сентября 2008

Хм, 1,7 миллиона строк? Я не решаюсь предложить это для такого рода нагрузки.

Вот один из способов сделать это с помощью LINQ.

CSVReader csvReader = new CSVReader();
List<string> source = new List<string>();
using(StreamReader sr = new StreamReader(myFileName))
{
  while (!sr.EndOfStream)
  {
    source.Add(sr.ReadLine());
  }
}
List<string> ServMissing =
  source
  .Where(s => s.StartsWith(" ")
  .ToList();
//--------------------------------------------------
List<IGrouping<string, string>> groupedSource = 
(
  from s in source
  where !s.StartsWith(" ")
  let parsed = csvReader.CSVParser(s)
  where parsed.Any()
  let first = parsed.First()
  let rest = String.Join( "," , parsed.Skip(1).ToArray())
  select new {first, rest}
)
.GroupBy(x => x.first, x => x.rest)   //GroupBy(keySelector, elementSelector)
.ToList()
//--------------------------------------------------
List<string> myExtras = new List<string>();
foreach(IGrouping<string, string> g in groupedSource)
{
  myHashTable.Add(g.Key, g.First());
  if (g.Skip(1).Any())
  {
    myExtras.Add(g.Key);
  } 
}
1 голос
/ 25 сентября 2008

Если у вас более 4 (например) значений CSV, возможно, стоит установить переменную value для использования StringBuilder, поскольку конкатенация строк является медленной функцией.

1 голос
/ 25 сентября 2008

Вот решение, которое позволяет избежать нескольких попаданий во вторичном списке с небольшими накладными расходами на все вставки:

Dictionary<T, List<K>> dict = new Dictionary<T, List<K>>();

//Insert item
if (!dict.ContainsKey(key))
   dict[key] = new List<string>();
dict[key].Add(value);

Вы можете заключить словарь в тип, который скрывает это, или поместить его в метод или даже метод расширения в словаре.

0 голосов
/ 25 сентября 2008

Спасибо всем. В итоге я использовал метод ContainsKey (). Это займет, может быть, 30 секунд дольше, что хорошо для моих целей. Я загружаю около 1,7 миллиона строк, и программе требуется около 7 минут, чтобы загрузить два файла, сравнить их и записать несколько файлов. Сравнение и запись файлов занимает всего около 2 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...