Rene Duchamp
Rene Duchamp

Reputation: 2629

Form doesn't load in while loop

I have a class defined to get live capture from a camera, and a form button "END CAPTURE" that should halt the capture; and an typical Application.Exit() button.

However, for some reason the while loop as shown below doesn't load the form even when the condition is met. To debug this, I commented out the while loop to see if it snaps at least 1 image; and it does (as shown in fig). What makes the while loop not to load the form and show the output continuously ?

while (!terminated)
            {
                // CAMERA ACQUISITION CODE
            }

Figure of single while loop run: 1

Full program for reference:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using mv.impact.acquire;
using mv.impact.acquire.examples.helper;


namespace mv_BlueFoxControl
{
    public partial class Form1 : Form
    {
        private bool button1WasClicked = false;
        public Bitmap SnappedBitmap = null;
        public static Image PersistentImage = null;

        public Form1()
        {
            InitializeComponent();

            mv.impact.acquire.LibraryPath.init(); // this will add the folders containing unmanaged libraries to the PATH variable.
            Device pDev = DeviceManager.getDevice(0);// Get a pointer to the first device found 

            if (pDev == null)
            {
                Console.WriteLine("Unable to continue! No device found! Press any key to end the program.");
                //Console.Read();
                Environment.Exit(1);
            }
            Console.WriteLine("Initialising the device. This might take some time...");
            try
            {
                pDev.open();//start the sensor
                Console.WriteLine("Device opened successfully...");
            }
            catch (ImpactAcquireException e)
            {
                // throw error code if the same device is already opened in another process...
                Console.WriteLine("An error occurred while opening the device " + pDev.serial +
                    "(error code: " + e.Message + "). Press any key to end the application...");
                //Console.ReadLine();
                Environment.Exit(1);
            }
            bool terminated = false;// Bool terminated was here.
            Console.WriteLine("Press CAPTURE to end the application");
            // create thread for live capture
            Thread thread = new Thread(delegate()//Start live acquisition
            {
                DeviceAccess.manuallyStartAcquisitionIfNeeded(pDev, fi);
                Request pRequest = null;
                // we always have to keep at least 2 images as the display module might want to repaint the image, thus we
                // can free it unless we have a assigned the display to a new buffer.
                Request pPreviousRequest = null;                
                int timeout_ms = 500;
                int cnt = 0;
                int requestNr = Device.INVALID_ID;
                Console.WriteLine(terminated); 
                while (!terminated)
                {
                    // CAMERA ACQUISITON CODE
                }
                DeviceAccess.manuallyStopAcquisitionIfNeeded(pDev, fi);                
                // free the last potential locked request
                if (pRequest != null)
                {
                    pRequest.unlock();
                }
                // clear the request queue
                fi.imageRequestReset(0, 0);
                // extract and unlock all requests that are now returned as 'aborted'
                requestNr = Device.INVALID_ID;
                while ((requestNr = fi.imageRequestWaitFor(0)) >= 0)
                {
                    pRequest = fi.getRequest(requestNr);
                    Console.WriteLine("Request {0} did return with status {1}", requestNr, pRequest.requestResult.readS());
                    pRequest.unlock();
                }
            });//End of thread
            Console.WriteLine(" End Thread");
            thread.Start();
            if (button1WasClicked)
            {
                terminated = true;
            }            
            Console.WriteLine("Program termination");
            Console.WriteLine(terminated);
            thread.Join();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            button1WasClicked = true;

        }
    }
}

Upvotes: 0

Views: 1384

Answers (1)

Jaime Mendes
Jaime Mendes

Reputation: 643

Because of thread.Join(); The application will wait that the thread ends (which will not end until you press the button) and so the constructor is never finished.

You have to initialize a Thread field and only close it when you press the button.

Try this:

public partial class Form1 : Form
{
    //...
    private Thread _cameraThread;

    public Form1()
    {
        //... the previous code 

        _cameraThread = new Thread(delegate()//Start live acquisition
        {
            // thread logic 
        });

        _cameraThread.Start();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        button1WasClicked = true;
        //set the flag and wait for the thread to finish
        _cameraThread.Join();
        Console.WriteLine("Program termination");
    }
}

Upvotes: 4

Related Questions