views:

87

answers:

1

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"

A: 

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.

jonp
Thanks for the effort jonp. I like your explanation. It made sense.The code you've provided does not seem to be much different from my code. Actually your code crashes my app without the try catch.I have a problem that abperson book will attempt to GetPhones() and at the first, second, or even twentieth spot it will start to complain Handle must not be null. Sometimes it will even run all the way through and get all of the phone numbers. I get different results by simply hitting the button that initiates it all again. Any other ideas for me?Thanks
Bryan