Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared IEnumerable<T> and IQueryable<T> in a multi-threaded application

I've few doubts regarding how shared IEnumerable and IQueryable is accessed in multi-threaded application.

Consider this code snippet.

ObservableCollection<SessionFile> files = /* some code */
IEnumerable<Pattern> allFilePatterns= /*some query */

foreach (Pattern pattern in allFilePatterns)
{
   string iclFilePath = Path.Combine(pattern.Location, pattern.Filename);
   SessionFile sfile = new SessionFile(iclFilePath, pattern.AnalysisDate);

   SomeDelegate invoker = new SomeDelegate(sfile.SomeHandler);
   invoker.BeginInvoke(allFilePatterns, null, null);

   files.Add(sfile );
}

As you can see, I'm using BeginInvoke() passing the same instance allFilePatterns to each handler called sfile.SomeHandler.

Suppose in SomeHandler, I iterate allFilePatterns in a foreach loop, something like this:

void SomeHandler(IEnumerable<Pattern> allFilePatterns)
{
    foreach(Pattern pattern in allFilePatterns)
    {
          //some code
    }
}

Now my doubt is that: since BeginInvoke() is asynchronous, that means all foreach in all SomeHandler of all the files would execute parallelly (each in its own thread), would the shared instance of IEnumerable enumerate as expected/normal? Is this a right approach? Can I share same instance of IEnumerable in multiple threads, and enumerate it parallelly?

And what if I use IQueryable instead of IEnumerable in the above code? Any side-effect that I should be aware of?

If its not thread-safe, then what should I use?

Please note that I'm using IQueryable for database queries, as I don't want to pull all the data from database. Therefore, I want to avoid IQueryable.ToList() as much as possible.

like image 491
Nawaz Avatar asked Apr 15 '11 12:04

Nawaz


People also ask

What is the difference between IEnumerable T and IQueryable T?

The major difference between IQueryable and IEnumerable is that IQueryable executes query with filters whereas IEnumerable executes the query first and then it filters the data based on conditions.

Which is better IEnumerable or IQueryable?

So if you working with only in-memory data collection IEnumerable is a good choice but if you want to query data collection which is connected with database `IQueryable is a better choice as it reduces network traffic and uses the power of SQL language.

Is IEnumerable thread safe?

As MSDN correctly states, "enumerating through a collection is intrinsically not a thread-safe procedure". Even if you use a synchronized collection (or one of the concurrent collections in . NET 4.0), and all methods use a lock statement internally, iteration using foreach may still fail.

Is LINQ thread safe?

They're not thread safe.


1 Answers

It depends on the implementation. Some implementations of IEnumerable<T> also implement IEnumerator<T>, and return themselves from GetEnumerator(). In that case it's obviously not thread-safe...

As for IQueryable<T>, it also depends on the implementation. For instance, Entity Framework contexts are not thread-safe, and will only work properly on the thread that created them.

So there is no unique answer to that question... it will probably work for some implementations, and not for others.

like image 163
Thomas Levesque Avatar answered Sep 18 '22 01:09

Thomas Levesque