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]] *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] <mailto:[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] <mailto:[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] <mailto:[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] <mailto:[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] <mailto:[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


Reply via email to