Valid Threading


Hey gurus,

I've created a small threading test and I would like to see what you all think.  
Basically I want to know if I am breaking any threading rules.

Ok this is the Code.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
using System.Data;
using System.Data.SqlClient;

namespace ThreadingTest
{
      /// <summary>
      /// Summary description for Form1.
      /// </summary>
      public class Form1 : System.Windows.Forms.Form
      {
            private System.Windows.Forms.CheckedListBox clstSettings;
            /// <summary>
            /// Required designer variable.
            /// </summary>
            ///
            
            //Thread
            private Thread thOpenDatabaseConnection;

            private System.ComponentModel.Container components = null;

            public Form1()
            {
                  //
                  // Required for Windows Form Designer support
                  //
                  InitializeComponent();

                  //Setup the open database connection thread
                  thOpenDatabaseConnection = new Thread(new ThreadStart(OpenDatabaseConnection));
                  thOpenDatabaseConnection.Name = "Open Database Connection";
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.clstSettings = new System.Windows.Forms.CheckedListBox();
                  this.SuspendLayout();
                  //
                  // clstSettings
                  //
                  this.clstSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
                  this.clstSettings.Location = new System.Drawing.Point(8, 8);
                  this.clstSettings.Name = "clstSettings";
                  this.clstSettings.SelectionMode = System.Windows.Forms.SelectionMode.None;
                  this.clstSettings.Size = new System.Drawing.Size(504, 229);
                  this.clstSettings.TabIndex = 2;
                  //
                  // Form1
                  //
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(520, 254);
                  this.Controls.Add(this.clstSettings);
                  this.Name = "Form1";
                  this.Text = "Threading Test";
                  this.Load += new System.EventHandler(this.Form1_Load);
                  this.ResumeLayout(false);

            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                  Application.Run(new Form1());
            }

            private void CheckLine(int nIndex, bool bValue)
            {
                  clstSettings.SetItemChecked(nIndex,bValue);
                  this.Refresh();
            }

            private int AddLine(string strString)
            {
                  int nReturn = 0;

                  nReturn = clstSettings.Items.Add(strString,CheckState.Unchecked);
                  this.Refresh();

                  return nReturn;
            }

            private void Form1_Load(object sender, System.EventArgs e)
            {
                  //Let the user know we are checking the database connection...
                  int nLine1 = AddLine("Verifying database connection settings");
                  //Check Line 1
                  CheckLine(nLine1,true);

                  //Run the open database connection thread
                  thOpenDatabaseConnection.Start();
            }

            private void OpenDatabaseConnection()
            {
                  try
                  {
                        //Attempt to open the database connection
                        int nLine2 = AddLine("Opening a database connection");

                        //Create a new sql connection object
                        SqlConnection sqlCn = new SqlConnection();

                        //Set the connection string
                        sqlCn.ConnectionString = "Persist Security Info=False;Initial Catalog=Db;Data Source=MAIN\\SQL";

                        sqlCn.Open();

                        //Check Line 2
                        CheckLine(nLine2,true);

                        int nLine3 = AddLine("Database connection verified!");
                        //Check Line 3
                        CheckLine(nLine3,true);

                  }
                  catch
                  {
                                          
                        //Add a line to say that the database connection failed
                        int nLine4 = AddLine("Database connection failed!");
                        //Check Line 4
                        CheckLine(nLine4,true);
                  }

            }
      }
}
ACanadianAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

smeggheadCommented:
the main thing, and common mistake people make when threading is that they can't talk directly to the gui.. any command to change any of the GUI should be called using Invoke...

So, when you are calling checkline from your thread, this is in turn calling a GUI update.
ACanadianAuthor Commented:

How does one use invoke to communicate with the GUI?
ACanadianAuthor Commented:

And what is the reason behind having to use invoke. Everything works fine if you don't.  Maybe .net doesn't need to use this invoke dealy.

Tim
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

AlexFMCommented:
1) All UI operations from the worker thread should be done using Invoke or BeginInvoke. Direct call from the worker thread may cause unpredictable results because .NET framework keeps some data in the thread local storage (TLS) and when you call UI functions from another thread, this data is not available. If your particular program works now, it doesn't mean this is right.

2) You run the worker thread without any control over it. To make professional multi-threaded program you need to control the thread execution - to stop the thread at any time when this is required. I think this article can help you:

http://www.codeproject.com/csharp/workerthread.asp

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
smeggheadCommented:
To call something, using invoke, the following syntax can be used

      private delegate void ThreadWorkerDef(NotifyEventArgs e);
      public void UpdateHandler(object sender,NotifyEventArgs e)
      {
            this.Invoke(new ThreadWorkerDef(ThreadWorker),new object[1] {e});
      }

      public void ThreadWorker(NotifyEventArgs e)
      {
            // Code to update the UI
      }
ACanadianAuthor Commented:
I gave the points to AlexFM because he posted information on a great example.

Thanks

smeggheadCommented:
Fair enough, but do you know you can split point.. I also told you everything you needed to know. And gave you an example which works.

Smg.
ACanadianAuthor Commented:
The other example did work as well, however yours was simpler.  

I suppose I could have split the points but are point really that important?  

Tim
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.