Monotoch GetPhones ABMultiValue Несогласованный

Я использую следующий код для получения номеров телефонов из адресной книги.

ABAddressBook mybook = new ABAddressBook();
ABPerson[] allPeople =  mybook.GetPeople();
foreach(ABPerson thisPerson in allPeople){


      if(thisPerson.GetPhones() != null)
             ABMultiValue<string> myMultiPhone = thisPerson.GetPhones();

      }
}

Обтекание кода в try-catch работает частично, но не всегда. Иногда он не получает все номера телефонов без проблем, а иногда он перестает получать номера телефонов случайным образом, и попытка перехвата выдает сообщение "произошла ошибка при получении телефонных номеров. Дескриптор не должен быть нулевым. Имя параметра: дескриптор"

1 ответ

Не делайте этого - в частности, не вызывайте ABPerson.GetPhones() подряд. ABMultiView<string> оборачивает собственный ресурс (именно поэтому ABMultiValue; реализует IDisposable.

Лучший способ был бы:

var mybook = new ABAddressBook();
foreach (var person in mybook.GetPeople()) {
    using (var phones = person.GetPhones()) {
        if (phones != null) {
            // do something with phones...
        }
    }
}

Это будет гарантировать, что ресурсы будут очищены, не полагаясь на GC, чтобы очистить их позже.

Тем не менее, я не уверен, почему ваш пример кода дает сбой. Выполнение финализатора выполняется в отдельном потоке, поэтому я думаю, что таким образом вы создаете много "мусорных" объектов (создавая два ABMultiValue<string> экземпляры для каждого человека), сборщик мусора помечает некоторые из них как мусор, а затем входит финализатор и запускает деструктор... который вызывает собственный код для очистки ресурса... но собственная библиотека может не быть поточной здесь безопасно Просто предположение.

Другие вопросы по тегам