Solved

Challenging Multithread Question 500points

Posted on 2004-10-07
5
238 Views
Last Modified: 2010-04-15
I am creating a Multithreaded C# Application.  The application will query a database for "jobs" to execute.  If it finds available jobs it will create a new "Job Object" (based on parameters supplied from the dataset returned from the query) and a  fresh worker thread for each job to be run.  This all works great.  I know that when the method (doSomeWork in the below example)  that the new thread calls exits the thread terminates.
Thread workthread = new Thread(new ThreadStart(doSomeWork));

What I need to accomplish is keeping track of all currently running threads.  When the thread is created it will increment an int variable, and decrement that variable when the thread exits.  I would also like to uniquely identify each thread.  So I can have, say a list box on a Winform showing currently executng threads.  So, essentially how do I monitor/track/label existing threads?

500 Points for some help.
0
Comment
Question by:mandalorian4
  • 2
  • 2
5 Comments
 
LVL 6

Accepted Solution

by:
boblah earned 500 total points
ID: 12249129
Hi mandalorian4,

Create a singleton object (Design patterns, GoF) - basically an object that has a single instance that all the different threads can access.

Have methods for threads to register themselves with it, and notify it when they are finished. (be careful the finish call is robust, with error trapping and finally etc)

The front end can then interrogate the singleton for the current status.

Below is an example of a singleton I wrote once for a situation where various different threads were accessing a printer resource for which we only had five licenses - so only five threads at any one time could do the printing.

It should be reasonably clear how to modify it for your situation, although it does contain a bunch of stuff you don't need. Note the locking for the thread count etc. I guess you would add a collection to store references to the threads that register themselves with the singleton.

To get a reference to the instance of the singleton, use the following code:

            CrLicenseLock oCrLicenseLock = CrLicenseLock.GetInstance();

the class is as follows:

        private sealed class CrLicenseLock
        {
            private int mnLicenseCount = 0;
            private const int LICENSE_COUNT_MAX = 3;
            private const int TIMEOUT = 1000;
            private AutoResetEvent moARE = null;

            #region Constructor etc
            static readonly CrLicenseLock instance=new CrLicenseLock();
            /// <summary>
            /// the method could easily be converted to a property with only an accessor,
            /// with no impact on thread-safety or performance.
            /// </summary>
            /// <returns></returns>
            public static CrLicenseLock GetInstance()
            {
                return instance;
            }
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static CrLicenseLock()
            {
            }
            public CrLicenseLock()
            {
                moARE = new AutoResetEvent(false);
            }
            #endregion

            #region External Methods
            #region LicenseGet
            /// <summary>
            /// should only be called from a try block, with a finally block containing the LicenseReturn
            /// would be improved by implementing a queuing system,
            /// would avoid numerous threads all hitting license count simultaneously
            /// however, only scaling issue, and if it were an issue
            /// the number of cr licenses would be woefully inadequate.
            /// </summary>
            /// <returns></returns>
            //
            public bool LicenseGet()
            {
                bool bReturn = false;
                bool bFirstTime = true;

                DateTime dtStart = DateTime.Now;

                do
                {
                    if(bFirstTime)
                        bFirstTime = false;
                    else
                    {
                        //all will clamour when signalled, but not big problem
                        moARE.WaitOne(TIMEOUT - DateTime.Now.Subtract(dtStart).Milliseconds, false);
                    }

                    lock(this)
                    {
                        if(mnLicenseCount < LICENSE_COUNT_MAX)
                        {
                            mnLicenseCount++;
                            bReturn = true;
                        }
                    }
                }while(bReturn == false && DateTime.Now.Subtract(dtStart).Milliseconds < TIMEOUT);

                return bReturn;
            }
            #endregion
            #region LicenseReturn
            public void LicenseReturn()
            {
                lock(this)
                {
                    mnLicenseCount--;
                }
                moARE.Set();
            }
            #endregion
            #endregion
        }


Cheers!
0
 
LVL 3

Author Comment

by:mandalorian4
ID: 12249622
boblah,

Thank you for the prompt response.  I will try to incorporate your solution shortly.  I noticed you used.

I am afraid I still do not understand how to identify a thread when multiple threads are created.  I see in my locals window a thread ID, but I do not see how to set or get the property.



Thank you.
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 12249655
AppDomain.GetCurrentThreadId() returns the unique id of the current thread.
You can assign a name to a thread.
To increment / decrement values threadsafe you can use the Interlocked.Decrement / Interlocked.Increment methods. (Evaluate the return value not the value in the variable)
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 12249661
BTW: You can not set the thread id. It's given by the system.
0
 
LVL 6

Expert Comment

by:boblah
ID: 12254069
mandalorian4,

More details on creating a singleton

    /// <summary>
    /// Summary description for SingletonTest.
    /// This object works as a singleton
    /// for details of why this is the best way to do a proper, thread safe, lazy loaded singleton
    /// (one other way for full lazy loading, but slightly higher performance cost)
    /// see: http://www.yoda.arachsys.com/csharp/singleton.html
    /// sealed declaration is not strictly necessary, but might help optimisation
    /// </summary>
    public sealed class SingletonTest
    {
        public string CreateTime = "";

        #region Constructor etc
        private static readonly SingletonTest instance = new SingletonTest();
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static SingletonTest()
        {
        }
        public SingletonTest()
        {
            CreateTime = System.DateTime.Now.ToString();
        }
        /// <summary>
        /// the method could easily be converted to a property with only an accessor,
        /// with no impact on thread-safety or performance.
        /// </summary>
        /// <returns></returns>
        public static SingletonTest GetInstance()
        {
            return instance;
        }
        #endregion


    }
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Article by: Ivo
C# And Nullable Types Since 2.0 C# has Nullable(T) Generic Structure. The idea behind is to allow value type objects to have null values just like reference types have. This concerns scenarios where not all data sources have values (like a databa…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question