0

我正在使用以下代码从通讯录中获取电话号码。

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


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

      }
}

将代码包装在 try catch 中有时会起作用,但并非总是如此。有时它会获取所有电话号码没有问题,有时它会停止随机获取电话号码,并且 try catch 抱怨“获取电话号码发生错误。句柄不能为空。参数名称:句柄”

4

1 回答 1

0

不要那样做——特别是不要像那样连续调用 ABPerson.GetPhones() 。包装原ABMultiView<string>生资源(这就是ABMultiValue<T>实现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>为每个人创建两个实例),GC 将其中几个标记为垃圾,并且终结器然后进入并运行析构函数...调用本机代码以清理资源...但是本机库在这里可能不是线程安全的。只是一个猜测。

于 2010-02-25T16:00:51.347 回答