Wal, The first reason I would avoid the ThreadStatic is because you don't have control of the Dispose. Your object will stay around in whatever threads happens to be initialized and will be disposed whenever. I don't like the idea of having those objects hanging around with no control of them. I like the idea of having them initialized/disposed deterministically once per thread via the alternate Parallel.ForEach.
On Mon, Feb 18, 2013 at 10:02 AM, Wallace Turner <[email protected]>wrote: > Dave, > > Please elaborate how it could actually cause a problem in this specific > case (besides the object-not-disposing automatically which Corneliu has > already mentioned) > > >You should avoid ThreadStatic (especially for a stateful object like a > hash code provider) when you don’t control the Thread creation > Why? > > >Underneath, you have no idea if you are going to be run on a thread for > each loop, or shared across a pool of worker threads. > Does this matter? Its new-ed in the loop. > > For the record I've never used [ThreadStatic] I think I read about it in > C# book and it seemed like an appropriate soln in this case (but the > overload Greg mentioned is much better) > > Cheers > > > On 2/18/2013 12:47 AM, David Kean wrote: > > You should avoid ThreadStatic (especially for a stateful object like a > hash code provider) when you don’t control the Thread creation. Underneath, > you have no idea if you are going to be run on a thread for each loop, or > shared across a pool of worker threads.**** > > ** ** > > Perhaps I’m missing something, but why isn’t this as simple as newing up a > new provider as a local at the start of the action, and disposing it at the > end?**** > > ** ** > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Corneliu I. Tusnea > *Sent:* Friday, February 15, 2013 4:49 PM > *To:* ozDotNet > *Subject:* Re: Crypto hash in a Parallel.ForEach**** > > ** ** > > Wal,**** > > ** ** > > That does not really work properly. You have to dispose the object as well > plus (I've tried it) every now and then it hits some odd error.**** > > I don't think [ThreadStatic] is safe to use with Parallel.ForEach.**** > > ** ** > > Corneliu,.**** > > ** ** > > ** ** > > On Fri, Feb 15, 2013 at 10:45 PM, Wallace Turner <[email protected]> > wrote:**** > > It should work fine... the following code does what its supposed to do :) > **** > > ** ** > > [ThreadStatic]**** > > private static object _hasher;**** > > ** ** > > ** ** > > var items = Enumerable.Range(1, 50);**** > > ** ** > > Parallel.ForEach(items, (i, state) =>**** > > {**** > > if (_hasher == null)**** > > {**** > > _hasher = new object();**** > > Console.WriteLine("new hasher for thread " + > Thread.CurrentThread.ManagedThreadId);**** > > }**** > > Console.WriteLine(i + " " + > Thread.CurrentThread.ManagedThreadId);**** > > **** > > });**** > > ** ** > > On Fri, Feb 15, 2013 at 7:37 PM, Wallace Turner <[email protected]> > wrote:**** > > attribute your hasher with [ThreadStatic] ? (and obviously move the > init check into the loop which would only be done once per thread)**** > > ** ** > > http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx* > *** > > ** ** > > On Fri, Feb 15, 2013 at 7:00 PM, Corneliu I. Tusnea < > [email protected]> wrote:**** > > I hit exactly the same issue with calculating hashes. I don't think it's > threadsafe to do it. Just initialize it in each thread. I found the > performance to be acceptable (at least for my use).**** > > However if you do find a better way I'd like to know :)**** > > ** ** > > On Fri, Feb 15, 2013 at 8:38 PM, mike smith <[email protected]> wrote:*** > * > > SOme of the stuff around here about TLS?**** > > ** ** > > http://msdn.microsoft.com/en-us/library/6sby1byh.aspx**** > > ** ** > > On Fri, Feb 15, 2013 at 7:25 PM, Greg Keogh <[email protected]> wrote:**** > > Folks, I can't remember if I've asked about this before. I think I year > ago when I hit this I gave up and worked around it ... but now I want it > solved!**** > > **** > > I have a Parallel.ForEach loop over EnumerateFiles which is blazing fast, > but then I added to code to make an MD5 hash of the files and it dies > because of "Hash not valid for use in specified state". I have a single > static MD5 hasher which lives for the life of the app, but calling it from > many threads is not allowed.**** > > **** > > I have a suspicion there is an overload of Parallel.ForEach that allows > each thread to start/use/finish its own resources. In theory I need each > thread needs to make its own MD5 and dispose at the end. There are so many > overloads in the Threading Tasks namespace that I'm confused at first and > I'll have to plod through Jeffrey Richter's book overnight to find a > possible example.**** > > **** > > Are there any Task ninjas out there who know how to do this sort of thing? > **** > > **** > > Greg K**** > > **** > > P.S. I just went to pat the cat and on the way back I picked up Richter's > CLR via C# and I found a skeleton example on page 742 where he adds up the > sizes of all files in a folder. However, the example is very terse and I'll > need to stare at it for a while to grok it. I will need to check that this > example behaves consistently under all conditions such as cancellation, > unhandled crash, etc. If I find anything useful I'll let you know.**** > > > > **** > > ** ** > > -- > Meski**** > > http://courteous.ly/aAOZcv**** > > > "Going to Starbucks for coffee is like going to prison for sex. Sure, > you'll get it, but it's going to be rough" - Adam Hills**** > > ** ** > > ** ** > > ** ** > > ** ** > > >
