i often populate data reader with data and populate UI like this way
using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("Select * from employee where salary<5000", conn))
{
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
// here i populate my employee class
}
}
// here i update UI
}
i was searching for the use of Task Parallel library with DataReader and found piece of code. it looks nice but objective is not very clear to me. so here is the code i got.
public IEnumerable<MyDataClass> ReadData()
{
using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("myQuery", conn))
{
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
yield return new MyDataClass(... data from reader ...);
}
}
}
}
calling like
Parallel.ForEach(this.ReadData(), data =>
{
// Use the data here...
});
OR
this.ReadData().AsParallel().ForAll(data =>
{
// Use the data here...
});
how could i get the data from ForAll.
can anyone help me to understand the code snippet that how it works and how to get data from ForAll and how can i populate my UI from ForAll.
another question that how do i know that which class is thread safe or not. what does it mean thread safe. a person said datareader is not thread safe. how he knows.
another question when one should use task parallel library. please guide. thanks
You can find information about thread-safety of every type in the .NET base class library in the MSDN documentation. Most types are not thread-safe. SqlDataReader
for instance, is not thread-safe, since it works on a single connection to the database.
However, Parallel.ForEach
is a very clearer construct. You can't really iterate an IEnumerable
with multiple thread simultaneously, and Parallel.ForEach
doesn't do that. Although it spins up multiple threads and those multiple threads do iterate on the given IEnumerable
, Parallel.ForEach
ensures that only one thread at the time iterates the enumerable's IEnumerator
. It operates on the assumption that processing elements takes more time than getting the items from the enumerable. Iterating the enumerable is a sequential operation.
This means that even if the underlying data source and the use of the SqlReader
is not thread-safe, you can still process the items in parallel using the Parallel.ForEach
. Unfortunately, the MSDN documentation isn't very explicit about this, but it has to be, since IEnumerator
instances returned from GetEnumerator()
methods are never thread-safe.
Still you have to make sure that the given Action<T>
is thread-safe, of course.
You can see this behavior, using the following program:
public static IEnumerable<int> GetNumbers()
{
for (int i = 0; i < 140; i++)
{
Console.WriteLine(
" Enumerating " +
i + " at thread " +
Thread.CurrentThread.ManagedThreadId);
yield return i;
}
}
static void Main(string[] args)
{
Console.ReadLine();
Parallel.ForEach(GetNumbers(), number =>
{
Console.WriteLine("Processing " + number +
" at thread " +
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With