using(s) inside a loop with a continue - c#

Given the following sample code:
var count = 0;
while (count < 5)
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
using (var response = await StaticHttpClient.Client.SendAsync(request))
{
if (!response.IsSuccessStatusCode)
{
switch ((int)response.StatusCode)
{
case 500:
case 504:
continue;
}
}
else
{ ... }
}
count++;
}
Will those IDisposable objects leak memory in this method or will the Dispose method be properly called? (There are many cases missing from the switch and I'm not concerned about the efficiency there).

Will those IDisposable objects leak memory in this method or will the Dispose method be properly called?
The disposables will get Dispose() called on them properly since you used a using statement. When you continue, the Dispose() methods will be called prior to the next iteration of the loop.

Using statement will always call Dispose() this is the whole point of using it

Related

Understanding how using block dispose of objects

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.

Early exit from calling code when using yield return on a generic IEnumerable

What happens when calling code exits prior to completing enumeration of a IEnumerable that is yield returning.
A simplified example:
public void HandleData()
{
int count = 0;
foreach (var datum in GetFileData())
{
//handle datum
if (++count > 10)
{
break;//early exit
}
}
}
public static IEnumerable<string> GetFileData()
{
using (StreamReader sr = _file.BuildStreamer())
{
string line = String.Empty;
while ((line = sr.ReadLine()) != null)
{
yield return line;
}
}
}
In this case it seems quite important that the StreamReader is closed in a timely manner. Is there a pattern needed to handle this scenario?
That's a good question.
You see, while using foreach() to iterate resulting IEnumerable, you're safe. The Enumerator below implements IDisposable itself, which gets called in case of foreach (even if loop is exited with break) and takes care of cleaning the state of your in GetFileData.
But if you will play with Enumerator.MoveNext directly, you're in trouble and Dispose will never be called if exited earlier (of course, if you'll complete manual iteration, it will be).For manual Enumerator-based iteration, you can consider placing enumerator in using statement as well (as mentioned in code below).
Hope this example with different usecases covered will provide you some feedback for your question.
static void Main(string[] args)
{
// Dispose will be called
foreach(var value in GetEnumerable())
{
Console.WriteLine(value);
break;
}
try
{
// Dispose will be called even here
foreach (var value in GetEnumerable())
{
Console.WriteLine(value);
throw new Exception();
}
}
catch // Lame
{
}
// Dispose will not be called
var enumerator = GetEnumerable().GetEnumerator();
// But if enumerator and this logic is placed inside the "using" block,
// like this: using(var enumerator = GetEnumerable().GetEnumerable(){}), it will be.
while(enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
break;
}
Console.WriteLine("{0}Here we'll see dispose on completion of manual enumeration.{0}", Environment.NewLine);
// Dispose will be called: ended enumeration
var enumerator2 = GetEnumerable().GetEnumerator();
while (enumerator2.MoveNext())
{
Console.WriteLine(enumerator2.Current);
}
}
static IEnumerable<string> GetEnumerable()
{
using (new MyDisposer())
{
yield return "First";
yield return "Second";
}
Console.WriteLine("Done with execution");
}
public class MyDisposer : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
Originally observed by: https://blogs.msdn.microsoft.com/dancre/2008/03/15/yield-and-usings-your-dispose-may-not-be-called/
Author calls this (the fact that manual MoveNext() and early break will not trigger Dipose()) "a bug", but this is intended implementation.

protobuf-net Stream is disposed before returning data

I have a webapi that returns some protobuf-net serialized items after being transformed from a database column. The number of items can be rather large so I'd like to avoid materializing them all in memory and rather stream them out however, I never get a single one out before my Stream throws an already disposed exception. If I materialize the list it does work but I'd like to avoid it.
Here is what I'm doing::
private override async Task<IEnumerable<MyObj>> GetRawData(int id)
{
using(var sqlConn = GetOpenConnection())
{
using (var sqlReader =(await sqlConn.ExecuteReaderAsync(
_workingQuery,new {id = id}, 60)
.ConfigureAwait(false) as SqlDataReader))
{
await sqlReader.ReadAsync().ConfigureAwait(false);
using (var stream = sqlReader.GetStream(0))
{
return _serializerModel.DeserializeItems<MyObj>(stream, PrefixStyle.Base128, 1)
}
}
}
}
private async Task<IHttpActionResult> TransformData(int id)
{
var data=await GetRawData().ConfigureAwait(false);
return Ok(new {Data=data.Where(m=>...).Select(m=>...)})
}
[HttpGet,Route("api/myroute/{id}"]
public async Task<IHttpActionResult> GetObjs(int id)
{
return await TransformData();
}
However, I end getting an error about reading a disposed stream. How can I avoid this error?
The long and short of it is that you are returning a non-enumerated sequence, and closing (disposing) everything it needs before it ever gets to the caller. You're going to need to either:
enumerate the sequence eagerly (buffer in memory) - for example, adding .ToList()
restructure the code so that nothing is disposed until the end of the iteration
For the latter, I would be tempted to use an iterator block for the central part (after all the await). Something like:
bool dispose = true;
SqlConnection conn = null;
//...others
try {
conn = ...
...await...
var result = InnerMethod(conn, stream, ..., )
// ^^^ everything now known / obtained from DB
dispose = false; // handing lifetime management to the inner method
return result;
} finally {
if(dispose) {
using(conn) {}
//.//
}
}
IEnumerable<...> Inner(...) { // not async
using (conn)
using (stream) {
foreach(var item in ...) {
yield return item;
}
}
}
This line
return _serializerModel.DeserializeItems<MyObj>(stream, PrefixStyle.Base128, 1)
Returns just an indexer. As you seem to be aware the result is not yet materialized. However, right after the return, the using block disposes your Stream.
The solution would be to have GetRawData return the Stream. Then, inside TransformData, inside a using block for the Stream, you deserialize, filter and return the results.
The second potential issue is that your current approach processes the whole result and then sends it to the client all at once.
In order to have Web API send a streamed result you need to use HttpResponseMessage, and pass a Stream to it's Content property.
Here's an example: http://weblogs.asp.net/andresv/asynchronous-streaming-in-asp-net-webapi
When you want to stream a Stream to another Stream (I know, it sounds funny), you need to keep the ReaderStream open until the WriterStream is done writing. This is a high level representation:
using (ReaderStream)
{
using (WriterStream)
{
// write object from ReaderStream to WriterStream
}
}

Enumerator disposal when not using using, foreach or manually calling Dispose()

I'm using yield return to iterate over an SqlDataReader's records:
IEnumerable<Reading> GetReadings() {
using (var connection = new SqlConnection(_connectionString))
{
using (var command = new SqlCommand(_query, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new Reading
{
End = reader.GetDateTime(0),
Value = reader.GetDouble(1)
};
}
}
connection.Close();
}
}
}
I'm then using an adapted version of this accepted answer to "zip" many iterators together:
var enumerators = data.Select(d => new
{
d.Key,
Enumerator = d.Value.GetEnumerator()
}).ToList();
while (true)
{
foreach (var item in enumerators)
{
if (!item.Enumerator.MoveNext())
{
yield break;
}
/*snip*/
}
/*snip*/
}
In the method above, the enumerator's Dispose() is not explicitly called, and because they are not used within a using or foreach statement, would the underlying iterator remain in an open state? In my case with an open SqlConnection.
Should I be calling Dispose() on the enumerators to make sure the whole downstream chain is closed?
When enumerating over this iterator, if the enumerator's Dispose() is not explicitly called, and not used within a using statement, would the underlying iterator remain in an open state?
Let me re-phrase that question into a form that is easier to answer.
When using foreach to enumerate via an iterator block that contains a using statement, are the resources disposed of when control leaves the loop?
Yes.
What mechanisms ensure this?
These three:
A using statement is just a convenient way to write a try-finally where the finally disposes of the resource.
The foreach loop is also a convenient syntax for try-finally, and again, the finally calls Dispose on the enumerator when control leaves the loop.
The enumerator produced by an iterator block implements IDisposable. Calling Dispose() on it ensures that all the finally blocks in the iterator block are executed, including finally blocks that come from using statements.
If I avoid the foreach loop, call GetEnumerator myself, and don't call Dispose on the enumerator, do I have a guarantee that the finally blocks of the enumerator will run?
Nope. Always dispose your enumerators. They implement IDisposable for a reason.
Is that now clear?
If this subject interests you then you should read my long series on design characteristics of iterator blocks in C#.
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/
You call Dispose to deallocate resources allocated by the connection and call Close to just close the connection. AfterClose call the connection may be pushed in connection pool, if runtime that found suitable, in case of Dispose, instead, it will be scheduled for destroy .
So all depends on what you mean saying "valid" state.
If it's enclosed in usingdirrective, which is nothing else then try/finally, you have a guarantee that even if any exception happen in iteration the connection will be closed and its resources will be destroyed. In other cases you have to handle all it by yourself.
Just to add some nuance to this:
Array-enumerators are NOT generic and are not disposable
Collection-enumerators ARE generic of and are disposable but only if T itself is a reference-type ... not a value-type
So if you use GetEnumerator(), be sure to use
IEnumerator arrayEnumerator = arrayToEnumerate.GetEnumerator();
IEnumerator<T> collectionEnumerator = collectionToEnumerate.GetEnumerator();
then later in your code
collectionEnumerator.Dispose(); // compiles if T is reference-type but NOT value-type
Examples:
object[] theObjectArray = [...]
IEnumerator arrayEnumerator = theObjectArray.GetEnumerator(); // does not return
IEnumerator<object> and is not disposable
arrayEnumerator.Dispose(); // won't compile
List<double> theListOfDoubles = [...]
IEnumerator<someObject> doubleEnumerator = doubleEnumerator.GetEnumerator();
doubleEnumerator.Dispose(); // won't compile
List<someObject> theListOfObjects = [...]
IEnumerator<someObject> objectEnumerator = theListOfObjects.GetEnumerator(); // disposable
objectEnumerator.Dispose(); // compiles & runs

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