Monotoch GetPhones ABMultiValue Inconsistent

420 views Asked by At

I am using the following code to get phones numbers from the address book.

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


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

      }
}

Wrapping the code in a try catch works part of the time, but not always. Sometimes it will get all of the phones numbers no problem, and other times it stops getting phones numbers randomly and the try catch complains "error occurred getting phone numbers. Handle must not be null. Parameter name: handle"

1

There are 1 answers

1
jonp On

Don't do that -- specifically, don't call ABPerson.GetPhones() in succession like that. The ABMultiView<string> wraps a native resource (which is why ABMultiValue<T> implements IDisposable.

A better way would be:

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

This will ensure that resources are cleaned up without relying on the GC to clean them up later.

However, I'm not sure why your code sample is crashing. Finalizer execution runs on a separate thread, so my best guess is that, because you're creating lots of "garbage" objects this way (creating two ABMultiValue<string> instances for each person), the GC is marking several of them as garbage, and the finalizer then comes in and runs the destructor...which calls into native code to clean up the resource...but the native library might not be thread safe here. Just a guess.