防止物体在使用块内处置
工作流程:
我有一个带有两种表单的 winform 应用程序,在第一种表单中,我查询 liteDB
并在 内操作
块检索数据。IEnumerable
实例使用
IEnumerable<student> searchResult;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
searchResult = col.Find(x => x.contact.phone == "123456789");
}
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
问题:
然后,我需要将 searchResult
元素发送到第二个表单才能向用户显示,正如您在上面代码的最后两行中看到的那样。
但由于它位于 using
块内,因此我得到 System.ObjectDisposeException
。
数据类型和异常:
studentCollection.Find()
: 
搜索结果
:
例外:
添加:
我已经想到的可能方法是:
覆盖并取消现有的 dispose()
方法,然后在完成后调用我自己实现的方法;这基本上等于没有 using
块,除了我不必处理上面 using
块中的其他对象,而只需处理 searchResult< ;学生>
。
PS: 我是整个事情的新手,感谢帮助和解释
Workflow:
I have a winform app with two forms, in the 1st form I query a liteDB
and it manipulates an IEnumerable<T>
instance inside a using
block with retrieved data.
IEnumerable<student> searchResult;
using(var db = new LiteDatabase(@"C:\Temp\MyData.db"))
{
var col = db.GetCollection<student>("students");
col.EnsureIndex(x => x.contact.phone);
searchResult = col.Find(x => x.contact.phone == "123456789");
}
Form2 frm2 = new Form2();
Form2.profileData = searchResult.AtElement(index);
Problem:
I then, need to send an element of searchResult<student>
to 2nd form in order to show user, as you can see in the last 2 lines of above code.
But since it's inside using
block, I get System.ObjectDisposedException
.
Data types and exception:
studentCollection.Find()
:

searchResult
:

Exception:

Addition:
What I already though of as possible way is:
Override and nullify existing dispose()
method then call my own implemented method after I'm done; Which is basically equals to not having a using
block, except that I don't have to take care of disposing other objects in above using
block, but only searchResult<student>
.
P.S:
I'm newbie at whole thing, appreciate the help and explanation
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不熟悉 LiteDb,但我假设它返回数据库的代理对象。因此,当数据库被处置后,代理对象就不再可用。
避免该问题的简单方法是在
.Find(...)
之后添加.ToList()
。这会将代理列表转换为内存中实际的List
,并且可以在数据库处理后使用它。列表中的student
对象也可能是代理,如果是这种情况,则会失败。如果是这种情况,您要么需要找到某种方法使数据库返回真实的非代理对象,要么将数据库的生命周期延长到比表单的生命周期更长,例如
请注意
的用法。 ShowDialog
,这将阻塞,直到第二个表单关闭。这并不是绝对必要的,但它使管理数据库的生命周期变得更加容易。I'm not familliar with LiteDb, but I would assume it returns a proxy object for the database. So when the database is disposed, the proxy-object is no longer usable.
The simple method to avoid the problem is to add
.ToList()
after the.Find(...)
. This will convert the proxy-list to an actualList<T>
in memory, and it can be used after the database is disposed. It is possible that thestudent
objects inside the list are also proxies, and if that is the case this will fail.If that is the case you either need to find some way to make the database return real, non-proxy objects, or extend the lifetime of the database to be longer than that of your form, for example
Note the usage of
.ShowDialog
, this will block until the second form has been closed. That is not strictly necessary, but it makes it much easier to manage the lifetime of the database.您需要在退出 using 块之前访问该元素。
You need to access the element before exiting the using block.