Realm如何关闭和阅读 [英] Realm how to close and read

查看:51
本文介绍了Realm如何关闭和阅读的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having an issue where I am encountering the following error: Realms.Exceptions.RealmClosedException when I try to read my list of realm objects after I retrieved them. The closing of realm is my desired behavior as in my logs I saw ~2K instances of crashes reporting Realm OOM exceptions so I decided to experiment with wrapping my call to realm in a using statement as so:

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 异常,以及如何在关闭后正确读取来自所述源的数据?

I then try to work with this data as follows (and that is when the exception is raised) allUsers.FirstOrDefault(x => x.PortalUserId == id.ToString());. allUsers in this case is the variable holding the data returned by the last block of code. Thus I am wondering what is the correct way to properly handle disposing of realm in order to ensure we don't run into OOM exceptions with it, and how to properly read the data from said source even after it has been closed?

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

The block which returns the users is inside of my UserRepository, the application implements the UnitOfWork pattern (to access our realm db) which is then accessed via DI.

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

Another follow up question would be: should I only wrap my calls to realm in a Using statement if it's only a CUD operation (Create, Update, Delete) whilst reads should not be wrapped in that and let the GC handle disposing of the realm instance as needed later?

推荐答案

我认为实际上你的问题有很多点.

I think that actually there are multiple points in your question.

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

The way that you dispose your realm really depends on whether you are on the main thread or on a background thread.

如果你在主线程上,那么你不应该处理你的领域,当你需要的时候调用 Realm.GetInstance() 或者将领域初始化为单例是有意义的,就像下面的代码片段:

If you are on a main thread then you should not dispose your realm, and it would make sense to either call Realm.GetInstance() when you need it, or to initialize the realm as a singleton, like in the following snippet:

public class MyViewModel
{
    private readonly Realm realm;

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

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

If you are on a background thread then you definitely need to dispose of the realm. In this case the using statement is probably the easiest thing to do:

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的大小增加.您可以在这个答案中阅读更多关于原因的信息.

You need to dispose of realm on background threads otherwise you will cause the increase of the size of the realm on the disk. You can read more about why in this answer.

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

Using ToList() on realm.All() is probably not a good idea, as you will load all the objects in memory losing the "laziness" of access. If what you need to do is find a certain object you can use a query like:

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

存储库

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

Repository

Realm does not really work well with the repository pattern. If you really want to use the repository pattern, then you will lose some of the advantages of working with realm, like the fact that the objects and collections are live and auto-updating. Besides, this is all made even more complicated by the use of background threads because of what I have said before.

这篇关于Realm如何关闭和阅读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆