Understanding how using block dispose of objects - c#

I have the following code, where I want to immediately dispose of ApplicationDbContext instance:
using (var context = ApplicationDbContext.Create())
{
MyRepository myRespository = new MyRepository(context);
myRepository.ReadData();
}
If C# garbage collector wants to immediately dispose of ApplicationDbContext, it would have to immediately dispose of MyRepository as well, because it has a reference to ApplicationDbContext? Is this actually happening?
Or do I need to write my code like below to ensure ApplicationDbContext is Disposed, immediately?
using (var context = ApplicationDbContext.Create())
using (MyRepository myRespository = new MyRepository(context))
{
myRepository.ReadData();
}

Your second block of code is right.
One using clause is applied to one declaration.
Wat you wrote here:
using (var context = ApplicationDbContext.Create())
using (MyRepository myRespository = new MyRepository(context))
{
myRepository.ReadData();
}
Is the same as:
var context = ApplicationDbContext.Create();
try
{
var myRespository = new MyRepository(context);
try
{
myRepository.ReadData();
}
finally
{
myRepository.Dispose();
}
}
finally
{
context.Dispose();
}
That's what the compiler generate for you, therefore you do not need to worry about writing such a heavy and repetitive thing which is a possible source of error and bugs.
In the first code, myRespository is not disposed.

Related

LinqToDB DataConnection not disposed upon exiting using block

This issue has been perplexing me for quite a while. I'm trying to dispose of a connection to a database, but it keeps leaking no matter how I try to dispose of it. Worse yet, it's supposed to dispose automatically.
Long story short, I have a HostedService that starts with the following code:
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = _serviceProvider.CreateScope())
{
_logger.LogDebug($"Инициализация операторов");
using (var operatorRepo = scope.ServiceProvider.GetService<IOperatorRepository>()) {
var availableOperators = operatorRepo.GetAllOperatorsWithSkills();
_logger.LogDebug($"Инициализовано {availableOperators.Count()} операторов");
foreach (OperatorRow opRow in availableOperators)
{
OperatorMeta opMeta = new(opRow.Idr, opRow.Name, opRow.Number, opRow.OperatorSkills.Select(skill => (skill.SkillId, skill.Experience)));
if (!TryAddOperator(opMeta))
throw new ArgumentException($"Оператор с id {opRow.Idr} уже был добавлен!");
}
if (Convert.ToBoolean(_configuration.GetSection("isOperatorTesting")?.Value))
{
_globalOperatorPool.TryAdd(
-1,
new CampaignOperator(
new OperatorMeta(-1, "Test operator", _configuration.GetSection("testOperatorNumber").Value, Enumerable.Empty<(int, int)>()),
OperatorState.Unassigned)
);
}
}
}
}
I have tried to wrap the insides of the using in a try finally blocks just in case but I honestly don't see how that would be an issue because the using isn't inside of one. Still, connection doesn't close.
The underlying class of IOperatorRepository extends from a chain of two classes which extend from LinqToDB.DataConnection. It's the only IDisposable in the chain.
Honestly, I'm stumped. Any help would be appreciated.
Edit: I feel like I should specify that the connection class does indeed return ObjectDisposedException, but the connection stays open in the database, and more are made constantly as if they're not being reused.

Two nested Entity Framework contexts, sharing a transaction

I have code that looks like the example below. There's an explicit transaction involved because of some database tomfoolery that needs to be done via a SP, and a save changes in the middle of it all. (Exception handling, rollbacks, etc.. omitted):
void OuterMethod(MyDatbase context)
{
using(var dbTrans = context.Database.BeginTransaction())
{
// some stuff, the save puts the data where the SP can see it
Stuff(context);
context.SaveChanges();
// now some SP stuff
context.Database.ExecuteSqlCommand(#"spFoo", params);
// more stuff
MoreStuff(context);
AlmostUnrelatedCode(context);
context.SaveChanges();
dbTrans.Commit();
}
}
Right now the method AlmostUnrelatedCode() -- which is only marginally related to the process above -- needs a nice, fast, disposable read-only context 99% of the time. I have a factory that will serve me up the right kind of context when I need it. The 1% of the time it's called from the middle of that block above.
MyDatabase localReadOnlyContext;
void AlmostUnrelatedCode(MyDatabase context)
{
if ( context.Database.CurrentTransaction != null )
{
// Must use the context passed or everything deadlocks :(
localReadOnlyContext = context;
disposeContextLater = false;
}
else
{
// I just want to do this all the time
localReadOnlyContext = _contextFactory.CreateReadOptimized();
disposeContextLater = true;
}
// Do many, many things with my read-optimized context...
// The Dispose() on the class will check for disposeContextLater
}
What I'd like to do is to get rid of that transaction check, and in fact not need to pass the outer context at all if I can help it.
What I've tried:
Just ignoring what's going on in the outer transaction and using the context I generate all the time. Problem: deadlocks.
Trying to get the outermost transaction into the EF context I create with the _contextFactory. Problem: EF context constructors don't allow you to pass an existing transaction; also Database.CurrentTransaction has no setter.
Pulling the whole transaction out into a TransactionScope that wraps everything up. Problem: the method OuterMethod passes in the context, and I don't have control of the caller.
What I can't try:
Dirty reads/nolock. AlmostUnrelatedCode() needs the data as written so far.
I'd rather not:
Just keep using the outer context while inside of AlmostUnrelatedCode. AlmostUnrelatedCode deals with a lot of data trees and that context gets fat and unhappy really fast. It pollutes its context with crap really fast, and I'd rather just dispose of it when I'm done.
you can prevent the deadlocks by using one connection for multiple contexts.
example
var efConnectionString = ConfigurationManager.ConnectionStrings["SomeEntities"].ConnectionString;
// note EntityConnection, not SqlConnection
using (var conn = new EntityConnection(efConnectionString)) {
// important to prevent escalation
await conn.OpenAsync();
using (var c1 = new SomeEntities(conn, contextOwnsConnection: false)) {
//Use some stored procedures etc.
count1 = await c1.SomeEntity1.CountAsync();
}
using (var c2 = new SomeEntities(conn, contextOwnsConnection: false)) {
//Use some stored procedures etc.
count2 = await c2.SomeEntity21.CountAsync();
}
}
in your case just get the connection from the context and reuse it
context.Database.Connection
Can't you separate things done in AlmostUnrelatedCode like this:
void AlmostUnrelatedCode()
{
var context = _contextFactory.CreateReadOptimized();
AlmostUnrelatedCode(context);
context.Dispose();
}
void AlmostUnrelatedCode(MyDatabase context)
{
// Do many, many things with context...
}
Now you can call AlmostUnrelatedCode(with param) from your OuterMethod. And maybe there is even more to be separated. Consider SOLID.

Object lifetime when created and used only in the scope of a using statement

When an object is created and used only within the scope of a using statement, is it disposed of during the disposal of its enclosing IDisposable instance? If not, why wouldn't it be?
For instance, when using Dapper I've often created an anonymous object within the scope of the SqlConnection with the impression that it will be disposed of sooner - however I recently read something to the contrary.
using (var connection = new SqlConnection("Connection String"))
{
var parameters = new
{
Message = "Hello world!"
};
connection.Execute("INSERT INTO...", parameters);
}
Your using statement is essentially equivalent to:
var connection = new SqlConnection("Connection String");
try
{
var parameters = new
{
Message = "Hello world!"
};
}
finally
{
if (connection != null)
{
((IDisposable)connection).Dispose();
}
}
As you can see, there is no reason why any other IDisposable instance created inside the try block be disposed automatically for you. If you do need to ensure other objects are disposed then simply nest using statements:
using (var connection = new SqlConnection("Connection String"))
{
using (var otherDisposableObject = new ....)
{
} //otherDisposableObject disposed
} //connection disposed
If excessive nesting gets in the way of readability, then you can simply write the using statements as follows:
using (var connection = new SqlConnection("Connection String"))
using (var otherDisposableObject = new ....)
using (var anotherDisposableObject = new ....)
using (var andAnotherDisposableObject = new ....)
{
} //andAnotherDisposableObject, anotherDisposableObject, otherDisposableObject and connection all disposed
Do bear in mind though that you seem to be mixing garbage collection with disposing an object. In your example, parameters is elegible for garbage collection once execution has exited the using statement as there is no live refence to it.
When it is garbage collected is up to the GC, it might very well never be, depending on your application's memory pressure. If it is garbage collected, then it will be marked as valid for finalization and the finalizer of the object will be scheduled to run. Again, if and when that happens is entirely up to the GC.
Lastly, if the IDisposable pattern of the object is implemented correctly and the finalizer is run, Dispose() will be called (to be precise, Dispose(false) will be called) and the object will dispose any unmanaged resources it might be holding (managed resources can not be disposed safely in this context but it really doesn't matter, the GC will eventually take care of them too).
See IDisposable Pattern for more details on how it works or even better, check out this excellent SO answer.

Dealing with nested "using" statements in C#

I've noticed that the level of nested using statements has lately increased in my code. The reason is probably because I use more and more of async/await pattern, which often adds at least one more using for CancellationTokenSource or CancellationTokenRegistration.
So, how to reduce the nesting of using, so the code doesn't look like Christmas tree? Similar questions have been asked on SO before, and I'd like to sum up what I've learnt from the answers.
Use adjacent using without indentation. A fake example:
using (var a = new FileStream())
using (var b = new MemoryStream())
using (var c = new CancellationTokenSource())
{
// ...
}
This may work, but often there's some code between using (e.g. it may be too early to create another object):
// ...
using (var a = new FileStream())
{
// ...
using (var b = new MemoryStream())
{
// ...
using (var c = new CancellationTokenSource())
{
// ...
}
}
}
Combine objects of the same type (or cast to IDisposable) into single using, e.g.:
// ...
FileStream a = null;
MemoryStream b = null;
CancellationTokenSource c = null;
// ...
using (IDisposable a1 = (a = new FileStream()),
b1 = (b = new MemoryStream()),
c1 = (c = new CancellationTokenSource()))
{
// ...
}
This has the same limitation as above, plus is more wordy and less readable, IMO.
Refactor the method into a few methods.
This is a preferred way, as far as I understand. Yet, I'm curious, why would the following be considered a bad practice?
public class DisposableList : List<IDisposable>, IDisposable
{
public void Dispose()
{
base.ForEach((a) => a.Dispose());
base.Clear();
}
}
// ...
using (var disposables = new DisposableList())
{
var a = new FileStream();
disposables.Add(a);
// ...
var b = new MemoryStream();
disposables.Add(b);
// ...
var c = new CancellationTokenSource();
disposables.Add(c);
// ...
}
[UPDATE] There are quite a few valid points in the comments that nesting using statements makes sure Dispose will get called on each object, even if some inner Dispose calls throw. However, there is a somewhat obscure issue: all nested exceptions possibly thrown by disposing of nested 'using' frames will be lost, besides the most outer one. More on this here.
In a single method, the first option would be my choice. However in some circumstances the DisposableList is useful. Particularly, if you have many disposable fields that all need to be disposed of (in which case you cannot use using). The implementation given is good start but it has a few problems (pointed out in comments by Alexei):
Requires you to remember to add the item to the list. (Although you could also say you have to remember to use using.)
Aborts the disposal process if one of the dispose methods throws, leaving the remaining items un-disposed.
Let's fix those problems:
public class DisposableList : List<IDisposable>, IDisposable
{
public void Dispose()
{
if (this.Count > 0)
{
List<Exception> exceptions = new List<Exception>();
foreach(var disposable in this)
{
try
{
disposable.Dispose();
}
catch (Exception e)
{
exceptions.Add(e);
}
}
base.Clear();
if (exceptions.Count > 0)
throw new AggregateException(exceptions);
}
}
public T Add<T>(Func<T> factory) where T : IDisposable
{
var item = factory();
base.Add(item);
return item;
}
}
Now we catch any exceptions from the Dispose calls and will throw a new AggregateException after going through all the items. I've added a helper Add method that allows a simpler usage:
using (var disposables = new DisposableList())
{
var file = disposables.Add(() => File.Create("test"));
// ...
var memory = disposables.Add(() => new MemoryStream());
// ...
var cts = disposables.Add(() => new CancellationTokenSource());
// ...
}
You should always refer to your fake example. When this is not possible, like you mentioned, then it is very likely that you can refactor the inner content into a separate method. If this also does not make sense you should just stick to your second example. Everything else just seems like less readable, less obvious and also less common code.
I would stick to the using blocks. Why?
It clearly shows your intentions with these objects
You don't have to mess around with try-finally blocks. It's error prone and your code gets less readable.
You can refactor embedded using statements later (extract them to methods)
You don't confuse your fellow programmers including a new layer of abstractions by creating your own logic
Your last suggestion hides the fact that a, b and c should be disposed explicitly. That`s why it's ugly.
As mentioned in my comment, if you'd use clean code principles you wouldn't run into these problems (usually).
Another option is to simply use a try-finally block. This might seem a bit verbose, but it does cut down unnecessary nesting.
FileStream a = null;
MemoryStream b = null;
CancellationTokenSource c = null;
try
{
a = new FileStream();
// ...
b = new MemoryStream();
// ...
c = new CancellationTokenSource();
}
finally
{
if (a != null) a.Dispose();
if (b != null) b.Dispose();
if (c != null) c.Dispose();
}

Does `using` dispose all the the objects declared in it?

I wonder if the object created in the usingstatement gets disposed if I perform a return or throw operation. Example as follows.
using(SomeClass thing = new SomeClass())
{
...
if(condition)
return;
...
}
Will the above get confused or is GC to be trusted here?
Yes, it will. The using statement will result in a finally block being created. A finally block's code will be run even if an exception is thrown in the related try block, or if there is a return statement in that try block.
There are only a few exceptions that can cause a finally block's code to not be executed, and they are all listed here, but my guess is that in your situation you'll be able to live with those consequences.
using is the equivalent of try-finally so, yes, it does.
dispose if it is implemented will always get called. Its the equivalent of calling dispose in a finally block.
It will dispose, yes. It will create a finally block in the CIL code.
Yes, because using is extended into a try finally by the compiler. The dispose will occur inside the finally block. Also, the finally will contain a test to check if the variables in the using are null (in case there are exceptions on the constructors).
When writing a using statement:
using(SomeClass thing = new SomeClass())
{
//...
if (condition)
return;
//...
}
this will result in the following code:
SomeClass thing;
try
{
thing = new SomeClass();
//...
if (condition)
return;
//...
}
finally
{
if(thing != null)
{
thing.Dispose();
}
}
So all object declared using ( /* HERE */ ) will get disposed automatically. Objects declared inside the {} won't.
But you can of course nest (or stack) using statements:
using (var thing = new SomeClass())
using (var another = new Another())
using (var somethingElse = new Whatever())
{
//...
}
which in turn of course is just the syntactic sugar for writing
using (var thing = new SomeClass())
{
using (var another = new Another())
{
using (var somethingElse = new Whatever())
{
//...
}
}
}
because when a statement is followed by just one block of code (in this case another using-block) you can skip the curly braces...
When using two or more objects of the same type you can chain the declaratio within the using-statement:
using (MemoryStream stream = new MemoryStream(), stream2 = new MemoryStream())
{
//...
}
(Thanks to #Gratzy for pointing that out)
For me, the question does not match with the details, and the details have been addressed here a bunch but not the title question...
Does using dispose all the the objects declared in it?
NO, it does not. It only calls Dispose() for the object(s) in its declaration. It does not call Dispose() for objects declared in it.
I usually see this kind of thing in code
using(var sqlConn = new SqlConnection("connStr"))
using(var sqlCmd = new SqlCmd("CmdText", sqlConn))
{
sqlConn.Open();
var reader = sqlCmd.ExecuteReader();
while (reader.Read())
{
//stuff is done
}
}
This will dispose and close both sqlConn and sqlCmd when the scope is complete for those but the reader that was declared in the using scope does not have Dispose() automatically called for it .

Categories

Resources