Monotoch GetPhones ABMultiValue 不一致

发布于 2024-08-22 18:35:22 字数 439 浏览 10 评论 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 会抱怨“获取电话号码时发生错误。句柄不得为空。 参数名称:句柄”

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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

莫言歌 2024-08-29 18:35:23

不要这样做——具体来说,不要像这样连续调用 ABPerson.GetPhones() 。 ABMultiView 包装了本机资源(这就是为什么 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 实例),GC将其中几个标记为垃圾,然后终结器进入并运行析构函数...它调用本机代码来清理资源...但本机库在这里可能不是线程安全的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文