• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 692
  • Last Modified:

Thread.Start caught in endless loop

The purpose of this program is to read from folder of images and do some calculations on the pixel values.  I've had some luck with some of the answers given here, but when I added some new functionality (a folderBrowserDialog) for some reason my button which is supposed to start the process stopped working.  The program gets caught in an endless loop when it is supposed to call the StartUpdate method.  Any help is appreciated, but I am not interested in more elegant ways to do this.  I am a beginner so extremely technical explanations are wasted on me.

Here is the code, minus the calculation logic:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;



namespace NewImageReader
{


    public partial class JpegReader : Form
    {
        // Variable declarations
        string openFileName;
        Thread updaterThread;

        delegate void ImageUpdaterDelegate(PictureBox imageHost, Bitmap image);
   
        public static void ImageUpdater(PictureBox imageHost, Bitmap image)
        {
            if (imageHost.InvokeRequired)
            {
                imageHost.Invoke(new ImageUpdaterDelegate(ImageUpdater), new object[] { imageHost, image });
            }
            else
            {
                imageHost.Image = image;
                imageHost.Refresh();
            }
        }



..............................................

        }
        // Bring up a dialog to open a file.
        private void button2_Click(object sender, EventArgs e)
        {
            bool fileOpened = false;

            FolderBrowserDialog filePath = new FolderBrowserDialog();


            // If a file is not opened, then set the initial directory to the
            // FolderBrowserDialog.SelectedPath value.
            if (!fileOpened)
            {
                folderBrowserDialog1.SelectedPath = @"G:\CodeProject\ProjectImages";
            }
            // Display the openFile dialog.
            DialogResult result = folderBrowserDialog1.ShowDialog();

            // OK button was pressed.
            if (result == DialogResult.OK)
            {

                textBox1.Text = folderBrowserDialog1.SelectedPath;
                openFileName = textBox1.Text;
               
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            updaterThread = new Thread(new ThreadStart(this.StartUpdate));
           
            updaterThread.Start();
            }
           
             public void StartUpdate()
        {                    
            foreach (string img in Directory.GetFiles(Path.GetDirectoryName(openFileName)))
            {
                LUBits(img);
               
            }

        }

        public JpegReader()
        {
            InitializeComponent();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }
     
       
           }
}
0
antarctican69
Asked:
antarctican69
  • 7
  • 5
  • 3
  • +1
3 Solutions
 
jhshuklaCommented:
Where is it getting caught in the loop? Before getting to StartUpdate or inside StartUpdate?
0
 
antarctican69Author Commented:
Before startUpdate, in the button1_Click event, as far as my debugging attempts have shown me.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Are there any exceptions being caught?...do you have any try/catch blocks where you are not using the exception?

Can you show more complete code?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
saraganiCommented:
I tried reproducing the problem using your code... I even took the LUBits code from your previous question, and I could not get the problem.

I even tried clicking button1 several times (I clicked it again before the previous thread ended with the pictures scanning) and it still worked.
0
 
antarctican69Author Commented:
If I use button_Click2 (which goes to the image processing logic) before I select the folder to process from it throws and exception/stops working.  I might be able to fix this, but I'd like to get it working first.  
Here is the complete code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;



namespace NewImageReader
{


    public partial class JpegReader : Form
    {
        // Variable declarations
        string openFileName;
       

        delegate void ImageUpdaterDelegate(PictureBox imageHost, Bitmap image);
   
        public static void ImageUpdater(PictureBox imageHost, Bitmap image)
        {
            if (imageHost.InvokeRequired)
            {
                imageHost.Invoke(new ImageUpdaterDelegate(ImageUpdater), new object[] { imageHost, image });
            }
            else
            {
                imageHost.Image = image;
                imageHost.Refresh();
            }
        }



        private void LUBits(String img)
        {
            Console.WriteLine(img);
            Bitmap bmp = new Bitmap(img) as Bitmap;

            ImageUpdater(imageHolder, bmp);
            //convert image to bitmap
            Bitmap avImg = new Bitmap(img);
            //Used for tally¬†
            double r = 0;
            double g = 0;
            double b = 0;

            int total = 0;

            for (int x = 0; x < avImg.Width; x++)
            {
                for (int y = 0; y < avImg.Height; y++)
                {
                    Color clr = avImg.GetPixel(x, y);

                    r += clr.R;
                    g += clr.G;
                    b += clr.B;

                    total++;
                }
            }

            //Calculate and display average¬†
            r /= total;
            String rString;
            rString = Convert.ToString(r);
            redLabel.Text = rString;

            g /= total;
            String gString;
            gString = Convert.ToString(g);
            greenLabel.Text = gString;

            b /= total;
            String bString;
            bString = Convert.ToString(b);
            blueLabel.Text = bString;


        }
        // Bring up a dialog to open a file.
        private void button2_Click(object sender, EventArgs e)
        {
            bool fileOpened = false;

            FolderBrowserDialog filePath = new FolderBrowserDialog();


            // If a file is not opened, then set the initial directory to the
            // FolderBrowserDialog.SelectedPath value.
            if (!fileOpened)
            {
                folderBrowserDialog1.SelectedPath = @"G:\CodeProject\ProjectImages";
            }
            // Display the openFile dialog.
            DialogResult result = folderBrowserDialog1.ShowDialog();

            // OK button was pressed.
            if (result == DialogResult.OK)
            {

                textBox1.Text = folderBrowserDialog1.SelectedPath;
                openFileName = textBox1.Text;
               
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Thread updaterThread = new Thread(new ThreadStart(this.StartUpdate));
           
            updaterThread.Start();
            }
           
             public void StartUpdate()
        {                    
            foreach (string img in Directory.GetFiles(Path.GetDirectoryName(openFileName)))
            {
                LUBits(img);
            }
        }

        public JpegReader()
        {
            InitializeComponent();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }
0
 
antarctican69Author Commented:
It worked?  That is what I expected since I had not made any changes to the threading logic, but it's not working on this end.
0
 
saraganiCommented:
Ok, I was using a previous code of your LUBits.
This code is different.

The problem here is that you are accessing the UI (redLabel, greenLabel and blueLabel) from another thread.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Your variable is called "openFileName" but you are assigning it a value from a FolderBrowserDialog?

Does it have a FILE path?...or a FOLDER path in it?

If it has a FOLDER path in it, then using Path.GetDirectoryName() in your StartUpdate() method is going to STRIP off the last folder!
0
 
saraganiCommented:
"If it has a FOLDER path in it, then using Path.GetDirectoryName() in your StartUpdate() method is going to STRIP off the last folder!"

Also correct. I noticed it and I added an extra "\" to the end of the openFileName so it will not fail in GetDirectoryName.


As Idle_Mind said, you already have the folder name, so you don't need to call the GetDirectoryName.
0
 
antarctican69Author Commented:
The code is not even making it to LUBits.  It is caught in a loop before StartUpdate.  I don't need to call GetDirectoryName?  OK, I waxed that and the code reads as

foreach (string img in Directory.GetFiles(openFileName))

Which works...so thank you guys much, this service is well worth it, and I hope you are well paid!
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
We are all volunteers here.  Glad we could help though...
0
 
saraganiCommented:
Please try the following code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;

namespace NewImageReader
{
    public partial class JpegReader : Form
    {
        // Variable declarations
        string openFileName;
        Thread updaterThread;

        public void UpdateUI(MethodInvoker mi)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(mi);
            }
            else
            {
                mi();
            }
        }

        private void LUBits(String img)
        {
            Console.WriteLine(img);
            Bitmap bmp = new Bitmap(img) as Bitmap;

            MethodInvoker mi = delegate()
            {
                imageHolder.Image = bmp;
                imageHolder.Refresh();
            };
            UpdateUI(mi);

            //convert image to bitmap
            Bitmap avImg = new Bitmap(img);
            //Used for tally 
            double r = 0;
            double g = 0;
            double b = 0;

            int total = 0;

            for (int x = 0; x < avImg.Width; x++)
            {
                for (int y = 0; y < avImg.Height; y++)
                {
                    Color clr = avImg.GetPixel(x, y);

                    r += clr.R;
                    g += clr.G;
                    b += clr.B;

                    total++;
                }
            }

            mi = delegate()
            {
                //Calculate and display average 
                r /= total;
                String rString;
                rString = Convert.ToString(r);
                redLabel.Text = rString;

                g /= total;
                String gString;
                gString = Convert.ToString(g);
                greenLabel.Text = gString;

                b /= total;
                String bString;
                bString = Convert.ToString(b);
                blueLabel.Text = bString;
            };
            UpdateUI(mi);

        }

        public JpegReader()
        {
            InitializeComponent();
        }

        // Bring up a dialog to open a file.
        private void button2_Click(object sender, EventArgs e)
        {
            bool fileOpened = false;

            FolderBrowserDialog filePath = new FolderBrowserDialog();

            // If a file is not opened, then set the initial directory to the
            // FolderBrowserDialog.SelectedPath value.
            if (!fileOpened)
            {
                folderBrowserDialog1.SelectedPath = @"G:\CodeProject\ProjectImages";
            }
            // Display the openFile dialog.
            DialogResult result = folderBrowserDialog1.ShowDialog();

            // OK button was pressed.
            if (result == DialogResult.OK)
            {

                textBox1.Text = folderBrowserDialog1.SelectedPath;
                openFileName = textBox1.Text;
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(openFileName) || !Directory.Exists(openFileName))
                return;

            button1.Enabled = false;
            button2.Enabled = false;
            updaterThread = new Thread(new ThreadStart(this.StartUpdate));
            updaterThread.Start();
        }

        public void StartUpdate()
        {
            foreach (string img in Directory.GetFiles(openFileName))
            {
                LUBits(img);
            }

            MethodInvoker mi = delegate()
            {
                button1.Enabled = true;
                button2.Enabled = true;
            };

            UpdateUI(mi);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Open in new window

0
 
antarctican69Author Commented:
Saragani,

Thanks for the rewrite, I'm sure your code is nicer than my clunky efforts, but this is for a class so I can't plagiarize.  It works for what I need, so many thanks again.
0
 
saraganiCommented:
Still, check if this code solves your problem.

You said that it appears that button1 click get stuck in an endless loop. It is hard to believe since there is nothing that can cause it.

On the other hand, you accesses the labels from another thread. This might cause some funky things (UI that hangs is one of them), and if you click on the "Pause" button on Visual Studio, you might see like the code is stuck on the wrong line... Appearance can be deceiving.

If you don't want to use my code then at least comment in your code all the places that change the Labels on LUBits and see if it solves your problem.

It that's the hole code then is defiantly a cross thread problem.
 
0
 
antarctican69Author Commented:
I will be experimenting with your code, just not right now. As it stands, the program runs very slowly (as per GetPixel) so I know it can be improved with Lockbits.  Your help will be noted in my write-up/project, as will this website.  Cheers.
0
 
antarctican69Author Commented:
I did not mean to make my comment the solution
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now