0

this is my first interaction here! I'm learning C# by myself, there will be a lot of errors beside to the bug i'm trying to get rid of, please be patient :)

I'm developing a very basic app that let you interact with serial ports, something like the tool integrated in Arduino. There is a button that is meant to Connect/Disconnect, it lanches/stops a Backgroundworker that keeps the form updated with new data. I've tryed to move .close(); every where in the code, but nothing changed, when I try to open it again it catches the Exception. And other apps con't access too. I think that I simply don't know what I'm doing :)

Can you help me releasing the resource?

The code involved in this operation:

 private void ConnectB_Click(object sender, EventArgs e)
    {
        if (!connected)
        {
            int baud = Convert.ToInt32(baudRate.SelectedItem.ToString());
            COMport = new SerialPort(COMpick.SelectedItem.ToString(), baud, Parity.None, 8, StopBits.One);
            try
            {
                COMport.Open();
                connected = true;
                ConnectB.Text = "Disconnect";
            }
            catch (ArgumentOutOfRangeException)
            {
                MessageBox.Show("Baud rate not valid.");
                connected = false;
            }
            catch (ArgumentException)
            {
                MessageBox.Show("Port name not valid.");
                connected = false;
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("Access denied, try close applications that may using the port.");
                connected = false;
            }

            if (backWorker.IsBusy != true)
            {
                backWorker.RunWorkerAsync();
            }
        }
        else
        {
            connected = false;

            backWorker.CancelAsync();

           ConnectB.Text = "Connect";
        }
    }

private void backWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        while (true)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else if(COMport.IsOpen)
            {
                // Get data and print it in the form
                try
                {
                    inbox = COMport.ReadLine() + '\n';
                }
                catch (InvalidOperationException) { }
               //Scroll down the form, passing something useless to make it work
                worker.ReportProgress(inbox.Length);
            }
        }

    }

   private void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.COMport.Close();
        this.COMport.Dispose();
    }

Thank you!

  • 2
    Use the Debug + Windows + Threads debugger window to debug this. You ought to see that calling CancelAsync() had no effect, your BGW is stuck in the ReadLine() call so doesn't check CancellationPending so never completes. Call Close() in your Click event handler to get it unstuck. Or use the DataReceived event handler so you don't need a BGW at all. – Hans Passant Nov 09 '14 at 18:22
  • Yet another alternative to using BackgroundWorker is to use the `SerialPort.BaseStream` object, calling the `Stream.ReadAsync()` method with the async/await pattern. Any of these three alternatives should work fine; note that all involve closing the `SerialPort` object from your GUI, where you know the call to `Close()` will actually execute. :) – Peter Duniho Nov 09 '14 at 19:03
  • @HansPassant Use Data received event is a great idea, but I'm afraid the GUI would freeze is a continuos stream is received! Tomorrow I will back home again and try out you solution. But anyway why don't post an answer instead of a comment? – OlimexSmart Nov 09 '14 at 20:02
  • @PeterDuniho I will study how the whole async/await thing work – OlimexSmart Nov 09 '14 at 20:06
  • @HansPassant I deleted the BGW and added a Datareceived event. The example given by Microsoft works fine (http://msdn.microsoft.com/it-it/library/system.io.ports.serialport.datareceived(v=vs.110).aspx) But in my form application the event doesn't fire at all! – OlimexSmart Nov 10 '14 at 16:37
  • Hmya, you'll have to document your question of course, click the Ask Question button. After reading [this post](http://stackoverflow.com/questions/8907490/serialport-not-receiving-any-data/8910167#8910167) first. – Hans Passant Nov 10 '14 at 16:59
  • @HansPassant I have solved the problem in the simplest way possible: I've added a Timer that every 10 millis updates the form. – OlimexSmart Nov 10 '14 at 17:54

0 Answers0