Q:

Threading - Multiple SerialPort and one DataGridView

I have 3 SerialPort components and 2 of them has DataReceived handlers.
When data is received, they are sending output through other SerialPort
(the third one).
I know that the possibility is not high in my application that both SerialPorts will try to send at the same time, but I tried to simulate this and of course I get an error that the COM PORT is being used.
private void sendToCOM(String comNumber, String msg, String speed)
    {
        try
        {
            using (SerialPort comPort = new SerialPort(comNumber, Int32.Parse(speed), Parity.None, 8, StopBits.One))
            {
                comPort.Open();
                comPort.Write(msg);
                comPort.Close();
                comPort.Dispose();
            }
        }
        catch(Exception ex)
        {
                cstFuncs.errorHandler(ex.Message, SettingsForm);
        }
    }

I understand that each SerialPort has it's own thread.
How can I make a queue or how can I prevent from both serial port to try access the same resources on the same time (and not loose the data that is supposed to be sent out)

A:

There are a few ways you could get locking in the sendToCOM method. This will stop the method from executing twice by causing any subsequent calls to wait until the first is complete. This isn't going to help if another process tried to use the same SerialPort, but it will stop any local contention.
One way would be to use the lock keyword on an object like so:
private readonly object _myLock = new object();

private void sendToCOM(String comNumber, String msg, String speed)
{
    try
    {
        lock(_myLock)
        {
            using (SerialPort comPort = new SerialPort(comNumber, Int32.Parse(speed), Parity.None, 8, StopBits.One))
            {
                comPort.Open();
                comPort.Write(msg);
                comPort.Close();
                comPort.Dispose();
            }
        }
    }
    catch(Exception ex)
    {
        cstFuncs.errorHandler(ex.Message, SettingsForm);
    }
}

Another way could be to use a ManualResetEventSlim (or something similar) to achieve the same effect:
private ManualResetEventSlim _myLock = new ManualResetEventSlim(true);

private void sendToCOM(String comNumber, String msg, String speed)
{
    _myLock.Wait();
    try
    {
        _myLock.Reset();
        using (SerialPort comPort = new SerialPort(comNumber, Int32.Parse(speed), Parity.None, 8, StopBits.One))
        {
            // ..
        }
    }
    catch(Exception ex)
    {
        cstFuncs.errorHandler(ex.Message, SettingsForm);
    } 
    finally
    {
        _myLock.Set();
    }
}

