As my project is growing, i've found myself needing to employ a new thread to carry out a loop task for the lifespan of my program. It all works seemingly well except for when I exit it.

It dosent close cleanly. By that I mean I have to press SHIFT+F5 to have it fully close, it seems to exit but I tried editing it and got the message "I cannot edit while the app is running".

Without the new thread starting I have no problem closing it.

If I start my app but do not start the new thread (which for the moment is triggered by a button click event) the app exits gracefully.

I have this line in the output window, which I cannot find a solution to via a search

"A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in System.Windows.Forms.dll"

As always I appreciate any help or advice.

Visual studio 2010
AMD x86

Suzie999;

What I might recommend is for you to post the code related to this "problem thread" here including any creation/disposal logic that you use so that others can possibly error check and troubleshoot the code directly :)

Please dont laugh at my code , its a little messy still :$

public static class Program
    {
        [DllImport("ImageSearchDLL.dll")]
        private static extern string ImageSearch(int _1, int _2, int _3, int _4, string _5);
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
                    
        }
        public static int[] FindImage(int L, int T, int R, int B, string F)
        {
            int[] aRTN = new int[5];
            
                //MessageBox.Show(R.ToString());
                string rtn = ImageSearch(L, T, R, B, F);
                //MessageBox.Show(rtn);
            
            if (rtn == "0")
            {
                
                aRTN[0] = 0;
                return aRTN;
            }
            else
            {
                string[] coords = rtn.Split('|'); //split return value of imagesearch into array
                //int[] aRTN = new int[5];          //declare int array with enough elements
                aRTN[0] = int.Parse(coords[0]);   //convert the string values into ints
                aRTN[1] = int.Parse(coords[1]);
                aRTN[2] = int.Parse(coords[2]);
                aRTN[3] = int.Parse(coords[3]);
                aRTN[4] = int.Parse(coords[4]);
                return aRTN;
            }

        }
    }
public partial class Form1 : Form
    {

        static string popupstate;
        static int popupintx;
        static int popupinty;
        static int popupintH;
        static int popupintW;

        public Form1()
        {
            InitializeComponent();
            
        }

        private void button1_Click(object sender, EventArgs e)
        {

            ThreadStart job = new ThreadStart(ClosePULoop);
            Thread thread = new Thread(job);

            if (button1.Text == "Start")
            {
                button1.Text = "Stop";
                Browser.Focus();
                Rectangle tang = new Rectangle(0, 0, 0, 0);
                tang = Browser.RectangleToScreen(tang);
                popupintW = tang.Size.Width;
                popupintH = tang.Size.Height;
                popupstate = button1.Text;
                popupintx = tang.X;
                popupinty = tang.Y;

                thread.Start();
            }
            else
            {
                button1.Text = "Start";
                popupstate = button1.Text;
                //ClosePULoop();
            }
            
        }
public static void ClosePULoop()
        {
            while (popupstate == "Stop")
            {
                int[] img = Program.FindImage(0, 0, 1024, 768, "C:\\Users\\Susan\\Documents\\buyproduct.bmp");
                bool b = img[0].Equals(1);
                if (b)
                {
                    int clk = Mouse.Close((img[1] - popupintx) + 5, (img[2] - popupinty) + 5);
                }
                else
                {
                    Thread.Sleep(1000);
                }
            }
            return ;
        }    
   }

Not being an expert on the use of threads here I'm just speculating based on a small (very small) amount of research I did here and a bit of intuitive reading within your code...

The only manipulation I'm seeing of your thread is:

  1. creation of thread within button1_click event
  2. sleep status change within else statement of while loop within ClosePULoop

Nowhere within your code am I seeing a termination of the thread which could be why the app is 'hanging' when you close it.

What I might suggest (again, I don't know much about threading, so just basing on a small amount of reading I did to try to help with this situation) would be a thread.Abort() somewhere wherever you're actually implementing a close of your application. Also, I notice that in the ClosePULoop Else statement your Thread.Sleep(1000) has a capital 'T' which doesn't match the variable 'thread' declared above.

Don't know if any of this will help or not but hope it does :)

Thanks for your input, it gave me something to think about with the Abort().
I think I have determined from that that its the loop that is causing the problem.
If I stop the loop before exiting it closes fully as expected, so the thread is dead.

So I have concluded I need a way to exit the loop(thread) on exit of the app in whatever fashion that may be.

In a scripting language I once tried there was an option in the code "OnScriptExitExecute" which basically run some code to close all items and set any enviroment setting back to normal or whatever code you wanted.

So I need something similar, although I was under the impression that the IDE would take care of something like that.

edit--

Regarding the Thread vs thread, I think that just sleeps the current thread as my gui is alive and responsive, which it was not without the new Thread.

Ok I found a solution to my problem, I might as well show it for future reference.

Old Code

ThreadStart job = new ThreadStart(ClosePULoop);
Thread thread = new Thread(job);

New Code

ThreadStart job = new ThreadStart(ClosePULoop);
Thread thread = new Thread(job);
thread.IsBackground = true; // this seems to ensure that the new thread is closed along with the main thread

Thank you again for your time and support.

Hey Suzie999, how did you get ImageSearchDLL.dll work in C#? I tried to implement it in c# but my application just crash without any exception when I call the function.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.