Why does Thread class not support IDisposable?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Creativ

    #1

    Why does Thread class not support IDisposable?

    Why does Thread class not support IDisposable? It's creating quite
    some problem. Namely, it can exhaust the resource and you have not
    control over it.
  • Jon Skeet [C# MVP]

    #2
    Re: Why does Thread class not support IDisposable?

    On Dec 7, 2:19 pm, Creativ <GongXinr...@gm ail.comwrote:
    Why does Thread class not support IDisposable?
    Why should it? What would Thread.Dispose actually do?
    It's creating quite some problem. Namely, it can exhaust the resource and you
    have not control over it.
    I've done a fair amount of threading and never got into a situation
    where I want to dispose of a thread. Now terminating a thread in a
    graceful manner is a different matter - but that's up to the
    collaboration between the threads. If you need to "hard" reset a
    thread, Abort is your friend - but you should only really do that if
    you're tearing down the process (or at least the AppDomain) as it
    leaves things in an indeterminate state.

    Jon

    Comment

    • Creativ

      #3
      Re: Why does Thread class not support IDisposable?

      The scenario I can think of is you create a thread to run some task.
      After some runs, quite some threads will be created. After doing that
      for a long time, you will have problem in creating Thread and run it
      since the CloseHandle will be called in the Finalizer.

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: Why does Thread class not support IDisposable?

        On Dec 7, 2:37 pm, Creativ <GongXinr...@gm ail.comwrote:
        The scenario I can think of is you create a thread to run some task.
        After some runs, quite some threads will be created. After doing that
        for a long time, you will have problem in creating Thread and run it
        since the CloseHandle will be called in the Finalizer.
        If you've got that many actual threads, you've got bigger problems
        anyway. Have you actually run into this as a problem? Have you seen
        anyone else running into this as a problem?

        Jon

        Comment

        • Creativ

          #5
          Re: Why does Thread class not support IDisposable?

          Yes, I did. Some one created a lot of thread to run some calculation.
          Finally he get an error from the numeric library, "Reached Thread
          Limit".
          I adviced him to use ThreadPool.
          But idealy, Thread should support IDisposable since it's a limited
          resource.

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: Why does Thread class not support IDisposable?

            On Dec 7, 3:17 pm, Creativ <GongXinr...@gm ail.comwrote:
            Yes, I did. Some one created a lot of thread to run some calculation.
            Finally he get an error from the numeric library, "Reached Thread
            Limit".
            But did you isolate the problem to finalization rather than it
            physically trying to run too many threads?
            I adviced him to use ThreadPool.
            But idealy, Thread should support IDisposable since it's a limited
            resource.
            But it's not something that *can* be manually released. There's the
            handle, but that's it - and I suspect that's not what you were seeing
            in the above situation.

            As I said before, if you're creating that many threads you will run
            into issues regardless.

            Jon

            Comment

            • Creativ

              #7
              Re: Why does Thread class not support IDisposable?

              As I said before, if you're creating that many threads you will run
              into issues regardless.
              The problem is as following. Since the Finalize() can be really
              delayed, the program will hold a lot of thread handle when those
              theads are ready. Implementing a Dispose which call CloseHandle() will
              solve this problem.

              Comment

              • Creativ

                #8
                Re: Why does Thread class not support IDisposable?

                Changing to ThreadPool, you won't get that kind problem.

                Comment

                • Jon Skeet [C# MVP]

                  #9
                  Re: Why does Thread class not support IDisposable?

                  On Dec 7, 3:32 pm, Creativ <GongXinr...@gm ail.comwrote:
                  As I said before, if you're creating that many threads you will run
                  into issues regardless.
                  >
                  The problem is as following. Since the Finalize() can be really
                  delayed, the program will hold a lot of thread handle when those
                  theads are ready. Implementing a Dispose which call CloseHandle() will
                  solve this problem.
                  Only if you know exactly when to call it - which you typically don't.

                  There are typically many, many, *many* times more handles available
                  than you sensibly want to create threads - in other words, if you're
                  creating enough threads to run into this as a problem, then you're
                  doing something wrong anyway.

                  It's like exceptions: there's a slight performance hit, but if you're
                  throwing enough to see a *significant* issue, then you're almost
                  certainly misusing exceptions in the first place.

                  Jon

                  Comment

                  • Chris Mullins [MVP - C#]

                    #10
                    Re: Why does Thread class not support IDisposable?

                    "Creativ" <GongXinrong@gm ail.comwrote:
                    Yes, I did. Some one created a lot of thread to run some calculation.
                    Finally he get an error from the numeric library, "Reached Thread
                    Limit".
                    I've gotta agree with Jon on this one. It's not a limitation in Windows
                    Threading, or the implementation of .Net thread constructs. The problem here
                    is the algorithm being used is deeply flawed.
                    I adviced him to use ThreadPool.
                    But idealy, Thread should support IDisposable since it's a limited
                    resource.
                    Threads are special. There's no way an external source can Dispose a thread.
                    It just isn't something that makes logical sense given the design of threads
                    in Windows.

                    An external source can set a flag, "Please Exit when you can", and the
                    thread can choose to honor that flag. Such a construct is common.

                    --
                    Chris Mullins


                    Comment

                    • Martin Carpella

                      #11
                      Re: Why does Thread class not support IDisposable?

                      Creativ <GongXinrong@gm ail.comwrites:
                      Changing to ThreadPool, you won't get that kind problem.
                      Of course not, because in this case no new threads are created but the
                      old ones are recycled. From a performance point of view, this is an
                      additional benefit of using the ThreadPool, as creating new threads can
                      be a quite expensive operation (DllMain calls, etc.).

                      Best regards,
                      Martin

                      Comment

                      • Peter Duniho

                        #12
                        Re: Why does Thread class not support IDisposable?

                        On Fri, 07 Dec 2007 07:17:46 -0800, Creativ <GongXinrong@gm ail.comwrote:
                        Yes, I did. Some one created a lot of thread to run some calculation.
                        Finally he get an error from the numeric library, "Reached Thread
                        Limit".
                        I adviced him to use ThreadPool.
                        And did that solve the problem? Can you post a sample of code that
                        demonstrates this "Reached Thread Limit" error, as well as an example of
                        how using ThreadPool avoids the problem?

                        I agree with Jon: this isn't an issue that IDisposable would address.
                        There's nothing for the Thread instance to dispose. If you are reaching
                        some limit on the number of threads, it's because the threads you've
                        already started haven't exited yet. Even assuming that Thread did
                        implement IDisposable, it would be a serious problem to dispose the object
                        before you're done with it (that is, before the thread has finished).

                        The solution to your friend's problem is to not start new threads before
                        the previously started ones have exited.

                        Using the ThreadPool might work around the issue, but only because it
                        won't allow additional new threads to begin execution as long as the
                        previously started threads haven't finished. Assuming that the original
                        bug causing the previously started threads to not finish isn't fixed, then
                        all that using ThreadPool will do is hide the "Reached Thread Limit" error
                        with a "my processing never completes" bug, or even an out-of-memory error
                        (eventually, the queue of threads will get so large that the program runs
                        out of memory...it might take awhile, maybe a very long while depending on
                        how the threads are started, for this to happen though).

                        Just because the "Reached Thread Limit" error goes away when you use
                        ThreadPool, that doesn't mean you've fixed your bug.
                        But idealy, Thread should support IDisposable since it's a limited
                        resource.
                        Being a "limited resource" isn't what defines whether something implements
                        IDisposable or not.

                        Memory is a limited resource. A simple Array object consumes this limited
                        resource. Yet, there's absolutely no reason for Array to implement
                        IDisposable, and implementing IDisposable on Array would not in any way
                        get around exhausting the limited resource through use of an Array.

                        The bottom line here: reaching the maximum number of threads is
                        representative of a bug in the code using the Thread class, and is _not_
                        representative of a defect in the design of the Thread class.

                        If you can post some sample code that demonstrates the problem, we'll be
                        able to point out the error in the code that's leading to the problem.
                        The "problem" being described is a non-problem, but we can at least offer
                        some advice as to how not to write buggy code. :)

                        Pete

                        Comment

                        • Peter Duniho

                          #13
                          Re: Why does Thread class not support IDisposable?

                          On Fri, 07 Dec 2007 09:01:51 -0800, Martin Carpella
                          <martin.carpell a@gmx.netwrote:
                          Creativ <GongXinrong@gm ail.comwrites:
                          >
                          >Changing to ThreadPool, you won't get that kind problem.
                          >
                          Of course not, because in this case no new threads are created but the
                          old ones are recycled.
                          Not if the basic logic causes the application to run out of threads
                          without ThreadPool. In that case, without a change to that basic logic,
                          using a thread pool the old ThreadPool threads aren't recycled because the
                          original delegate executing in the thread won't exit.

                          Instead, you just an ever-growing queue of new work items for the thread
                          pool.
                          From a performance point of view, this is an
                          additional benefit of using the ThreadPool, as creating new threads can
                          be a quite expensive operation (DllMain calls, etc.).
                          It's true, using a thread pool can be a nice way to handle certain
                          aysynchronous operations. But if you've got a bug with regular threads,
                          you've still got a bug using thread pool threads.

                          Pete

                          Comment

                          • Martin Carpella

                            #14
                            Re: Why does Thread class not support IDisposable?

                            "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rites:
                            Instead, you just an ever-growing queue of new work items for the thread
                            pool.
                            Yes, I completely agree with you. In my opinion it is exactly this queue
                            which will "solve"/hide the error, as there are never "too many"
                            threads, as the ThreadPool won't grow beyond its maximum thread count.
                            It's true, using a thread pool can be a nice way to handle certain
                            aysynchronous operations. But if you've got a bug with regular threads,
                            you've still got a bug using thread pool threads.
                            Again, agreed. If the problem is that there are too many concurrent
                            requests, though, the TreadPool _could_ be the solution, as, as you
                            mentioned, the work items get queued instead of spawning a new thread.

                            Best regards,
                            Martin

                            Comment

                            • Chris Mullins [MVP - C#]

                              #15
                              Re: Why does Thread class not support IDisposable?

                              You're still going to have problems.

                              If you've got all of the threadpool threads busy, you may end up deadlocking
                              the entire threadpool.

                              The think that keeps being danced around, is that a solution like this
                              performance waaaaay worse than a single-threaded soultuion. You're using all
                              system resources creating and scheduling threads. Almost no work is being
                              done towards your actual problem set.

                              Abuse of threads, be they custom threads, threadpool threads, IOCP threads,
                              or some new type I'm not aware of, all hurts performance and is an indicator
                              of a fundamentaly flawed desing.

                              .... breaking your work down into chunks, and passing those chungs to a set
                              of threads via a queue, is often the right design. You just can't point
                              1000+ threads at the queue and say "go!". At least not on a 1x, 2x, 4x, 8x
                              processor box.

                              --
                              Chris

                              "Martin Carpella" <martin.carpell a@gmx.netwrote in message
                              news:87wsrqur1c .fsf@msgid.carp ella.net...
                              "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rites:
                              >
                              >Instead, you just an ever-growing queue of new work items for the thread
                              >pool.
                              >
                              Yes, I completely agree with you. In my opinion it is exactly this queue
                              which will "solve"/hide the error, as there are never "too many"
                              threads, as the ThreadPool won't grow beyond its maximum thread count.
                              >
                              >It's true, using a thread pool can be a nice way to handle certain
                              >aysynchronou s operations. But if you've got a bug with regular threads,
                              >you've still got a bug using thread pool threads.
                              >
                              Again, agreed. If the problem is that there are too many concurrent
                              requests, though, the TreadPool _could_ be the solution, as, as you
                              mentioned, the work items get queued instead of spawning a new thread.
                              >
                              Best regards,
                              Martin

                              Comment

                              Working...