Do I need to call .Dispose() on the StandardAnalyzer, or does .Dispose() on the IndexWriter dispose its descendants? - lucene.net

Initializing an IndexWriter in Lucene.Net looks like this:
var analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(version);
var indexWriterConfig = new Lucene.Net.Index.IndexWriterConfig(version, analyzer);
Index = new Lucene.Net.Index.IndexWriter(luceneDir, indexWriterConfig);
That is, you can't instantiate an IndexWriter without an Analyzer. So, I would expect that calling .Dispose() on the IndexWriter would dispose its children, including the Analyzer. However browsing the code I don't see that happening - so far. Have I missed it?
So: Does calling .Dispose() on the IndexWriter dispose the Analyzer, and if not, why not?

IndexWriter does not dispose of the analyzer.
It doesn't dispose of the analyzer because it cannot be sure that you will not be using the analyzer elsewhere. It's a reference that it got via the constructor, it could be used by other IndexWriter instances without it knowing.
It's about ownership; you created the analyzer and let the writer use it. It is thus your responsibility to dispose of the analyzer.

Related

How can I require calling dispose method?

I'm trying to require (or at least warn in the linter) that when I create an object I also define when it should be disposed, if necessary. An example of this is the warning for Sink: Close instances of dart.core.Sink, which appears in VS Code if you create a Sink without ever calling .close(). The issue is that I have classes that define multiple Sink objects, so I close all of them in a dispose method for the class, which solves the dart.core.Sink warning but doesn't solve the underlying issue, because this method might never be called.
Is there any way to create a similar error/warning for my own classes? I've looked at adding new rules to the linter, but this seems like a lot of work, and before I go that far, I was wondering if there's any mixin or similar that would give me this functionality.
Your can use mustCallSuper attribute like this:
import 'package:meta/meta.dart';
#mustCallSuper
void dispose() {
// ...
}

Third Party Lib disposes context

Without the first two lines of the following, the Email is saved to the database just fine.
However, when I send the email using SendGrid's lib, an exception is thrown when the repository tries to save it, as the Context has been disposed.
System.ObjectDisposedException
It makes no sense to me unless the library is somehow mishandling threads or some such.
var response = await this._emailSender.SendEmailAsync(email);
email.ResponseStatusCode = (int)response.StatusCode;
this._emailRepository.Save(email);
My workaround is to create a new context:
var context = new ApplicationDbContext(this._options, this._applicationUserProvider);
context.Add(email);
context.SaveChanges();
Is there a better way to resolve this?
unless the library is somehow mishandling threads or some such.
It's an async method. The line after await may run on a different thread at a later time.
The place to look is in the calling code. If you call the method containing this line and don't wait/await the returned task, then the calling code can Dispose your DbContext while the email-sending Task is still running.

Why is my ApplicationDbContext getting disposed when I dispose of UserManager/RoleManager in my database initializer Seed()?

I'm playing with MVC 5, and I've created a website that uses ASP.NET Identity. I followed the steps in this blog post on MSDN to create a user and a role in the Seed method for my database initializer.
However, I noticed that the UserManager and RoleManager used in that code both implement IDisposable, so I changed the code slightly, to look something like this (and thus dispose them once I've finished with them):
protected override void Seed(ApplicationDbContext context)
{
using (var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)))
using (var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context)))
{
EnsureRoleCreated(roleManager, Roles.Administrator);
const string AdministratorUserName = "admin";
const string DefaultAdminPassword = "password";
var user = EnsureUserCreated(userManager, AdministratorUserName, DefaultAdminPassword);
EnsureUserIsInRole(userManager, user, Roles.Administrator);
}
base.Seed(context);
}
Now, when my controller actions attempt to access the DB, I get an exception saying that my DbContext has been disposed. (I new up a DbContext instance in the constructor for my controller).
[If I remove those using() statements and thus do not dispose the UserManager and RoleManager, then the problem goes away, so it's definitely those using() statements that are making the difference.]
This seems very odd to me. If the "correct" way to deal with this is to not explicitly dispose the UserManager and RoleManager, then surely they will still be disposed eventually when the garbage collector kicks in. Since this is unpredictable and could happen at any time, does this not mean that I have a ticking time-bomb in my application?
It seems to me that since I created the DbContext, I should be responsible for disposing of it. Why the heck are UserManager and/or RoleManager disposing of something they did not create?
It is the RoleStore that disposes the DbContext even if it did not create it.
The UserStore has a DisposeContext bool property that controls if the context should be disposed or not. The DisposeContext is false if you use the constructor that takes a DbContext as input.
This seems to have been fixed in the nightly builds. Here the RoleStore also have the DisposeContext property and seems to work as expected.

What is the difference between closing FileStream and setting it to null?

I have the following code to read and write a single line to a text file. Can we assign null to the reader and the writer objects at the end of the processing? or should I invoke Close() method? Thank you.
FileInfo JFile = new FileInfo(#"C:\test.txt");
using (FileStream JStream = JFile.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
StreamReader reader = null;
StreamWriter writer = null;
try
{
int n;
reader = new StreamReader(JStream);
string line = reader.ReadLine();
int.TryParse(line, out n);
n = n + 1;
writer = new StreamWriter(JStream);
JStream.Seek(0, SeekOrigin.Begin);
writer.WriteLine(n);
writer.Flush();
}
catch (Exception x)
{
string message = string.Format("Error while processing the file. {0}", x.Message);
System.Windows.Forms.MessageBox.Show(message);
}
reader = null;
writer = null;
}
Certain things need to happen when closing a file. For instance, when your program access a file, and creates a handle on it. .Close()-ing the stream allows the framework to immediately release the handle and other similar resources.
When you set it to null, you are relying on the garbage collector to do this important functionality for you. The GC might clean it all up now, or it might not. You dont know when it is going to happen. If your program crashes, it might never release the handle at all.
Its always a good idea to .Close() the stream yourself as soon as youre done.
You should be calling the Close method so that all the underlying unmanaged resources are freed. Setting the object to null, does not free up the resources. For details see http://msdn.microsoft.com/en-us/library/system.io.stream.close.aspx
Update: Since your code is inside using statement the Dispose method would be automatically called once execution is complete inside using statement.
When you set the object to null, you tell the CLR that you no longer need it and it is scheduled for Garbage Collection. The problem you will have is that the CLR's hooks into the file you have opened are not released until your program ends and the CLR is closed. When you invoke the Close() method, the file resources are cleaned up and then the bits and pieces are all scheduled for Garbage Collection properly.
if you open the streamreader in a using block it will take care of that for you as well but you loose some of the fine grained error handling you get with a try/catch/finally block.
Both the StreamReader and the StreamWriter implement IDisposable, which is their way of saying
"When you are done with me, please call this method (Dispose()) so I know you're done with me and I can clean myself up".
(This is also called Deterministic Finalization)
So you need to call Dispose on those, or wrap them in a using statement, which just does the same thing for you. In the case of these two classes, Dispose will internally call Close if it's not already closed.
You actually want to call Close() or better yet Dispose() to ensure all contents are flushed. You risk not having the buffer written if you do not explicitly close/dispose the Writer.
I think the best solution will be to use the using statment (like you did in FileStream).
It will take care of all the cleaning.

Entity Framework 4 ObjectContext Lifetime

Ive just started using EF4 with the repository pattern. Im having to call the dispose method after every use of context or wrap code arround in the using block. Can I use the ObjectContext without doing this in every method I write or is there a better way of handling this in the repository.
Also I dont want to pass the ObjectContext to the repository from the UI as well.
To do this as resource effectively as possible without dependency injection, I would suggest that you implement a private, lazy-loading property for the object context.
private ObjectContext _context;
private ObjectContext Context
{ get
{
return _context ?? (_context = new ObjectContext());
}
}
Next, make your repository implement IDisposable and take care of the object context in your dispose method:
public Repository : IDisposable
{
...
public void Dispose()
{
_context.Dispose();
}
}
Then, you just use the property in all your methods, and wrap usage of your repository in using statements.
To decrease traffic to the database, you could also factor out the saving to a separate method on the repository, which just forwards the call to the object context. That way you get more control of when data is saved in the UI layer, even though you don't control how. That means you could do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
repo.Save();
}
and there would only be one call from EF to the database. On the other hand, if you do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
}
nothing happens, which might be confusing.
The general pattern for using an object context is:
public BusinessObject GetSomething(){
using (MyObjectContext context = new MyObjectContext()){
//..do fun stuff
}
}
Which hopefully is the pattern you are using. Calling dispose seems a little overkill when you can just use a "using" statement.
Another option is if you are going to be doing multiple DB queries in a flow. I have seen a pattern where you can reuse the same context within the thread. People basically implement a Thread based singleton pattern and pass around the context. Advantages to this is not having to rebuild the context, as well as some in memory caching. Downside is you could run into concurrency issues. Someone updating something that you have cached internally in EF.
I am guessing the second case doesn't really apply because it sounds like you are writting a small app. (that statement was based on your comments about passing a context from UI...a statement which will scare any good code architect).
If you are interested in a thread based singleton. First learn about the Singleton pattern, and then check out this blog about "DataContext" threads. You will have to change the "DataContext" type to the ObjectContext class but it would work.
EDIT
I will say I overlooked an obvious solution and that would be the below ;). Just using a property based Object Context and playing your repository in a using statement. It would be the same as the using example above, but you would implement IDisoposable.