微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Realm如何关闭和阅读

如何解决Realm如何关闭和阅读

我遇到了以下错误Realms.Exceptions.RealmClosedException 当我在检索它们后尝试读取我的领域对象列表时。关闭领域是我想要的行为,因为在我的日志中,我看到了大约 2K 个崩溃实例报告领域 OOM 异常,因此我决定尝试将我对领域的调用包装在 using 语句中,如下所示:

List<RealmDomain.User> users;

using(var realm = Realm.GetInstance(config))
{
    users = realm.All<RealmDomain.User>().ToList();
}

return users;

然后我尝试按如下方式处理此数据(即引发异常时) allUsers.FirstOrDefault(x => x.PortalUserId == id.ToString());在这种情况下,allUsers 是保存最后一个代码块返回的数据的变量。因此,我想知道正确处理领域的正确处理方法是什么,以确保我们不会遇到 OOM 异常,以及如何在关闭后正确读取来自所述源的数据?

编辑:返回用户的块位于我的 UserRepository 内,应用程序实现了 UnitOfWork 模式(以访问我们的领域数据库),然后通过 DI 访问。

Edit2:另一个后续问题是:如果只是 CUD 操作(创建、更新、删除),我是否应该只将我对领域的调用包装在 Using 语句中,而读取不应该包装在其中并让 GC 处理稍后根据需要处理领域实例?

解决方法

我认为您的问题实际上有多个要点。

处理

您处理领域的方式实际上取决于您是在主线程上还是在后台线程上。

如果您在主线程上,则不应处置您的领域,并且在需要时调用 Realm.GetInstance() 或将领域初始化为单例是有意义的,如下面的代码片段所示:

public class MyViewModel
{
    private readonly Realm realm;

    public MyViewModel()
    {
        this.realm = Realm.GetInstance(); //or this.realm = RealmProvider.Singleton
    }
} 

如果您在后台线程上,那么您肯定需要处理该领域。在这种情况下, using 语句可能是最容易做的事情:

public async Task OnBackgroundThread()
{
    using(var realm = Realm.GetInstance()) //From C#8 you don't even need the braces
    {
        //do work with realm
    }
} 

您需要在后台线程上处理realm,否则会导致磁盘上realm的大小增加。您可以在 this answer 中详细了解原因。

ToList()

ToList() 上使用 realm.All() 可能不是一个好主意,因为您将加载内存中的所有对象,从而失去访问的“惰性”。如果您需要做的是找到某个对象,您可以使用如下查询:

realm.All<User>().Where(x => x.PortalUserId == id.ToString()).First();

存储库

Realm 不能很好地与存储库模式配合使用。如果您真的想使用存储库模式,那么您将失去使用领域的一些优势,例如对象和集合是实时的和自动更新的。此外,由于我之前说过的,使用后台线程使这一切变得更加复杂。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。