1

This may be a stupid question because I am new to C# but I am trying to send a signal using the serial port in a single send mode, and a continuous mode. I have a check box to indicate the send mode. When I click on the check box and click send, the application gets stuck in an infinite loop and I lose control of the application.

    private void bSend_Click(object sender, EventArgs e)
    {
        byte[] Break = new byte[1] { 0x00 };
        string input = tbTX.Text;
        byte[] bytesToSend = input.Split().Select(s => Convert.ToByte(s, 16)).ToArray();
        while (cbContinuous.Checked) // Checkbox named continuous
            {
                // Generate Break and MAB signal
                headerSignal();

                // Set back to DMX timing
                DMXSettings();
                mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

            }
        // Generate Break and MAB signal
        headerSignal();

        // Set back to DMX timing
        DMXSettings();
        mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

    }

Is there any way I can un-check the check box while it is in the infinite loop to regain control and stop sending? Or is there a better way that I can do this?

Gmann45
  • 21
  • 3
  • 2
    Have your main logic be in a different thread. Don't do long operations on the UI thread. Look into BackgroundWorkers, or async/await. – gunr2171 Aug 18 '14 at 18:51
  • 3
    do you ever uncheck your `cbContinous` box in code? if not your infinte loop is just the while loop there ... – Random Dev Aug 18 '14 at 18:56
  • like @gunr2171 said, you're tieing up your main thread – Jonesopolis Aug 18 '14 at 18:58
  • I would like the user to have control over the checkbox, I need the signal to be generated indefinitely until the box is unchecked. It also doesn't need to be a checkbox though, it can be a start and stop button too. – Gmann45 Aug 18 '14 at 19:44

2 Answers2

2

One solution is to use TPL (Task Parallel Library). An example of how you can do this, based on the code given in the question is as follows:

    private readonly List<Task> taskList = new List<Task>();

    private void bSend_Click(object sender, EventArgs e)
    {
        var task = Task.Run(() =>
        {
            byte[] Break = new byte[1] {0x00};
            string input = tbTX.Text;
            byte[] bytesToSend = input.Split().Select(s => Convert.ToByte(s, 16)).ToArray();
            while (cbContinuous.Checked) // Checkbox named continuous
            {
                // Generate Break and MAB signal
                headerSignal();

                // Set back to DMX timing
                DMXSettings();
                mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

            }
            // Generate Break and MAB signal
            headerSignal();

            // Set back to DMX timing
            DMXSettings();
            mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);
        });

        taskList.Add(task);
    }

You may also wish to disable certain elements of your GUI while this is running, to prevent subsequent button clicks from running the task again at the same time.

You may wish to read this question on Stack Overflow before using Application.DoEvents:

Use of Application.DoEvents

You may also wish to consider that .NET 4.5 has support for Asynchronous Programming via the await and async keywords:

Asynchronous Programming with Async and Await (C# and Visual Basic)

Community
  • 1
  • 1
Aalawlx
  • 593
  • 5
  • 25
0

Place a call to DoEvents inside your while loop:

   mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

   Application.DoEvents();
}
Reg Edit
  • 6,719
  • 1
  • 35
  • 46