which is better, closing a datareader or setting it to null? - datareader

I would like to know the advantage and disadvantage of the following operation
shall i better set the datareader to null than calling the close method. If this is good what are the advantages, else what is the problem in using so?.

You should use the using statement instead:
using (var reader = sqlCommand.ExecuteReader())
{
// do stuff
}
That way, you are sure that the reader is closed (disposed), even if an exception was raised in the "do stuff" block.
For a complete example, see this MSDN page.
Update (regarding your comment):
The using statement is in fact nothing else than a try-finally block to ensure that the reader is disposed (closed) in every case. E.g. the above code is equivalent to this:
SqlDataReader reader = null;
try
{
reader = sqlCommand.ExecuteReader();
}
finally
{
reader.Dispose(); // closes the reader
}

Related

Proper usage of cache.putIfAbsent() in Cache2k

I am wondering how to work with the putIfAbsent() method when using the Cache2k cache. In the ConcurrentHashMap for example, one works with the method like this:
Set<X> set = map.get(name);
if (set == null) {
final Set<X> value = new HashSet<X>();
set = map.putIfAbsent(name, value);
if (set == null) {
set = value;
}
}
(Copied from Should you check if the map containsKey before using ConcurrentMap's putIfAbsent)
The Cache2K version returns a boolean. What does that mean and what does this tell me when more than 1 thread inserts a value using the same key.
Any help would be greatly appreciated as I am a bit unsure on how to deal with this. I am using the latest version 0.26-BETA.
Thanks and best regards,
Michael
putIfAbsent() is equivalent to:
if (!cache.containsKey(key)) {
cache.put(key, value);
return true;
} else {
return false;
}
except that it is executed atomically.
The method returns true, if the value was inserted (that implies it was not existing before). Since it is executed atomically, only the thread, which value was successfully inserted, gets the true value.
Mind that put may invoke a writer, if registered. The writer is not invoked, if the value is already present.
The semantic of this method is identical to JCache/JSR107. This behavior might not make sense for all situations or is intuitive. See a discussion in https://github.com/jsr107/jsr107spec/issues/303.
If you like, please try to explain in another question about your use case or you desired cache semantics, so we can discuss what the best approach might be.

Conditional exception raising in a flow block

While using Akka's data-flow DSL, I have twice encountered a need to throw an exception inside future, conditionally. This is how I am doing it:
flow {
// ...
if (someCond)
shiftUnit(throw new SomeException)
else
Future().apply()
// ...
}
Is this the correct way to do it? Or is there a better approach?
The approach seems correct (although my knowledge is a bit rusty), you can even leave out the other branch, the following works for me (Scala 2.10.1):
flow { if (x == 2) shiftUnit(throw new Exception) }
which results in a Future[Unit].

.NET Rx - ReplaySubject buffer size not working

I've been using .NET Reactive Extensions to observe log events as they come in. I'm currently using a class that derives from IObservable and uses a ReplaySubject to store the logs, that way I can filter and replay the logs (for example: Show me all the Error logs, or show me all the Verbose logs) without losing the logs I've buffered.
The problem is, even though I've set a buffer size on the subject:
this.subject = new ReplaySubject<LogEvent>(10);
The memory usage of my program goes through the roof when I use OnNext to add to the observable collection on an infinite loop:
internal void WatchForNewEvents()
{
Task.Factory.StartNew(() =>
{
while (true)
{
dynamic parameters = new ExpandoObject();
// TODO: Add parameters for getting specific log events
if (this.logEventRepository.GetManyHasNewResults(parameters))
{
foreach (var recentEvent in this.logEventRepository.GetMany(parameters))
{
this.subject.OnNext(recentEvent);
}
}
// Commented this out for now to really see the memory go up
// Thread.Sleep(1000);
}
});
}
Does the buffer size on ReplaySubject not work? It doesn't seem to be clearing the buffer when the buffer size is reached. Any help much appreciated!
UPDATE:
I add subscribers like this (Is this wrong?):
public IDisposable Subscribe(IObserver<LogEvent> observer)
{
return this.subject.Subscribe(observer);
}
...which is called like:
// Inserts into UI ListView
this.logEventObservable.Subscribe(evt => this.InsertNewLogEvent(evt));
I'm not sure if this is the definitive answer, but I suspect that you're hitting an issue because of concurrency around the scheduler you're using. The constructor you're calling on ReplaySubject looks like this:
public ReplaySubject(int bufferSize)
: this(bufferSize, TimeSpan.MaxValue, Scheduler.CurrentThread)
{ }
The Scheduler.CurrentThread worries me. Try changing it to Scheduler.ThreadPool and see if that helps.
Also, as a side note, you seem to be mixing Rx with TPL and old fashioned thread sleeping. It's usually best to avoid doing that. You could change your WatchForNewEvents code to look like this:
dynamic parameters = new ExpandoObject();
var newEvents =
from n in Observable.Interval(TimeSpan.FromSeconds(1.0))
where this.logEventRepository.GetManyHasNewResults(parameters)
from recentEvent in
this.logEventRepository.GetMany(parameters).ToObservable()
select recentEvent;
newEvents.Subscribe(this.subject);
That's a nice compact Rx-y way of doing things.

Reader close and dispose

Please look at the code. we have a method like this which returns reader. ie
public IRecordsReader GetValues()
{
IRecordsReader TestReader.....
return TestReader;
}
and we are calling that method inside another method like this
IRecordsReader ResultReader = GetValues();
ResultReader.Close();
ResultReader.Dispose();
ie we are closing and disposing that reader.
My doubt is that we are not properly closing the TestReader in the GetValues() method. So whether it will cause any connection pool issues? Please give your suggestions.
You should probably wrap your SqlDataReader with using so that it would automatically close and dispose the IDisposable object.
Like below
using(IRecordsReader ResultReader = GetValues())
{
//do your stuff
}
//resultReader is closed and disposed from now
More Info
since you do this
public IRecordsReader GetValues()
{
IRecordsReader TestReader.....
return TestReader;
}
and this
IRecordsReader ResultReader = GetValues()
this is what you are actually doing
IRecordsReader ResultReader = TestReader
so you are indirectly closing/disposing the TestReader instance. You get it?. Put it in code and try you will know :)
Answer
OP Asked -So whether it will cause any connection pool issues? Please give your suggestions.
Unless your connection limit is not exceeded you won't have a issue. But since you are closing and disposing the resource you will not have any issues :)

return statement from within using

using (IDbCommand command = new SqlCommand())
{
IDbDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
adapter.SelectCommand = command;
command.Connection = _dataAccess.Connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetProcData";
command.Parameters.Add(new SqlParameter("#ProcID ", procId));
adapter.Fill(ds);
return ds.Tables[0].AsEnumerable();
}
This returns an IEnumerable DataRow The question is that since the return is within the using statement, will it property dispose of the IDBCommand? I know I can easily refactor this so I change the scope of the DataSet outside of the using, but it is more of a wonder than anything else.
Yes, this will work as expected with IDbCommand being properly disposed. The compiler will transform the using block to a try-catch-finally, where Dispose is invoked in the finally block.
Yes, the DB Command will be disposed, so far so good.
You can get troubles with IEnumerables. Because the items could potentially be produced when getting them from the IEnumerable, not when creating the IEnumerable, that is the nature of it. So it depends on how ds.Tables[0].AsEnumerable() is implemented. It could wait with executing the command until you get the first item. This is in the calling code, outside of the using block. You'll get an error, because the command had been disposed.
This is probably not an issue here, but should always be considered when returning IEnumerables (or lambda expressions) from a using block:
using (A a = new A())
{
return someItems.Select(x => a.Get(x));
}
When accessing the first item, a is already disposed and you get an error.
The IDbCommand is disposed correctly. As a rule of thumb when returning from within a using statement you are fine to do so so long as:
The thing you are returning isn't in the clause of the using
statement
The thing being returned isn't a reference created within the block of the using statement.
In the first case the using statement will dispose of the thing you are trying to return and in the second case the variable will go out of scope.
e.g.
//this is fine as result is createsd outside the scope of the block.
bool result = false;
using (SmtpClient mailClient = new SmtpClient())
{
try
{
mailClient.Send(...);
result = true;
}
catch(SmtpException)
{
result = false;
}
finally
{
return result;
}
}
Here, the using(){ ... } statement is our friend. When we exit the block our SmtpClient is disposed, and the result condition will still exist for you to use.
However, say we are writing a WinForm app or WPF app and we wrap a using block around our data context then we create a problem as the context disappears before the control can consume it.
// this will fail when you bind the customers to a form control!
using (DbContext context = new DBContext())
{
context.Customers.Where(c => c.Name.Contains("Bob")).Load();
return context.Customers.Local;
}
Here, the using(){ ... } statement hurts us. As when we come to dataBind our customer to a GridView (or other such databound control) the fact that we have disposed of the DbContext will mean our form has nothing to bind to so it will throw an exception!
HTH
The scope of your IDbCommand object is very clear: between the brackets { and }. As soon as your program flow exits from there, the object is disposed.