Solved

Challenging Multithread Question 500points

Posted on 2004-10-07
5
233 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Memory Usage 2 50
Resolve Dependency Issues 4 47
Replace &lt; with < 14 56
Eagerly loading related objects in entity framework 5 26
Introduction                                                 Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.   Also called…
Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

867 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now