why is access to com port denied?
Asked Answered
S

6

18

the code:

static void Main(string[] args)
{
    Console.WriteLine("Memory mapped file reader started");

    using (var file = MemoryMappedFile.OpenExisting("AIDA64_SensorValues"))
    {
        using (var readerz = file.CreateViewAccessor(0, 0))
        {
            var bytes = new byte[567];
            var encoding = Encoding.ASCII;
            readerz.ReadArray<byte>(0, bytes, 0, bytes.Length);

            File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes));

            var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
            using (var reader = XmlReader.Create("C:\\myFile.txt", readerSettings))
            {
                while (reader.Read())
                {
                    using (var fragmentReader = reader.ReadSubtree())
                    {
                        if (fragmentReader.Read())
                        {

                            reader.ReadToFollowing("value");
                            SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
                            port.Open();
                            port.Write(reader.ReadElementContentAsString() + ",");
                        }
                    }
                }
            }    
        }
    }

    Console.WriteLine("Press any key to exit ...");
    Console.ReadLine();
}

it reads shared memory, writes that shared memory to file, then the same file is opened with xml reader and splits xml since it has multiple roots, then gets the value of a node on each new split xml and sends over serial. it works on the first split xml and its node is sent over serial then it stops with a access is denied to com port message on attempt for writing second node to serial.

i have another app i made with same serial code and it works fine(i just tired it then closed it.)... so its strange.

Shortage answered 28/8, 2011 at 7:41 Comment(1)
maybe you're not closing some references properly and opened accessor means to deny more access from same app/thread?Favorable
S
34

You can open a serial port only once. But your code has the Open() call inside the while loop. That will only work for the first pass through the loop, kaboom on the 2nd pass. @cdhowie's solution doesn't work either, SerialPort has a quirk (aka bug) that the documentation warns about. It needs time to let a worker thread exit after the Dispose() or Close() call. The amount of time is unspecified and unpredictable.

The real solution is simple, just move the Open() call before the while loop.

Seafarer answered 28/8, 2011 at 11:9 Comment(0)
G
5

In addition to Hans' answer:

I had the same problem and played around a bit with some sleep times between opening and closing the serial port. In my case 250 ms were sufficient. Maybe this will help out somebody out there.

EDIT:

I optimized my solution and this is what I came up with:

int maxRetries = 20;
const int sleepTimeInMs = 50;
string loggingMessage = string.Empty;

while (maxRetries > 0)
{
    try
    {
        loggingMessage = "Opening serial port '" + mSerialPort.PortName + "'...";
        mSerialPort.Open();
        loggingMessage += "Succeeded.";
        IOLogger.LogInfo(loggingMessage);
        break;
    }
    catch (UnauthorizedAccessException unauthorizedAccessException)
    {
        maxRetries--;
        loggingMessage += "Failed (UnauthorizedAccessException): ";
        IOLogger.LogError(string.Format(loggingMessage + unauthorizedAccessException.Message + " -> Retrying in about {0} milliseconds...", sleepTimeInMs));
        Thread.Sleep(sleepTimeInMs);
    }
    catch (Exception exception)
    {
        loggingMessage += "Failed: ";
        IOLogger.LogError(loggingMessage + exception.Message);
    }
}

You can play around with the sleepTimeInMs and/or the maxRetries. I have chosen those values because they seemed to be sufficient in any needed use case.

Gastroenterology answered 15/6, 2016 at 15:20 Comment(0)
R
2

You need to close and dispose the port if it's opened because he is not disposed at the last connection.

Rephrase answered 3/7, 2019 at 8:33 Comment(0)
A
0

Hans' answer supercedes this one; I am leaving it for context and informational purposes only.


You need to close the port when you are done with it. The garbage collector is not collecting the first SerialPort object before you try to open another handle to it. Change this code:

SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write(reader.ReadElementContentAsString() + ",");

To:

using (SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One))) 
{
    port.Open();
    port.Write(reader.ReadElementContentAsString() + ",");
}
Anemone answered 28/8, 2011 at 7:42 Comment(2)
Hmm, that's interesting. I'm leaving my answer for informational reasons.Anemone
Does the using call port.close(); when its cleaning up?Negotiant
E
0

The Solution that worked for me is as follow: 1: use try catch block and put all the code of opening and closing port in it.

2: Use IsOpen() Function to check whether port is already opened or not.

3: If any exception (Access is denied) occurs, write the Port.Close() code in your catch block to free that port.

4: Make object of Serial port before try catch block to make it universal.

5: The Open() call should not be inside the loop. you should open the port only once and after the loop, you should close it.

If you follow all these steps you will never get this issue again.

A sample code is given below:

GsmCommMain comm = new GsmCommMain(COMPort.ToString(), 9600, 500);

try{ for (int i = 0; i < dtObj.Rows.Count; i++)
                                    {
                                        if (dtObj.Rows[i]["smsNumber"] != null)
                                        {
                                            if (dtObj.Rows[i]["smsNumber"].ToString() != "")
                                            {
                                                if (dtObj.Rows[i]["status"].ToString() != "Sent")
                                                {
                                                    Thread.Sleep(Convert.ToInt32("50000"));
                                                    string txtMessage = dtObj.Rows[i]["sms"].ToString();
                                                    string txtDestinationNumbers = dtObj.Rows[i]["smsNumber"].ToString();
                                                    bool unicode = true;
                                                    SmsSubmitPdu[] pdu = SmartMessageFactory.CreateConcatTextMessage(txtMessage, unicode, txtDestinationNumbers);
                                                    comm.SendMessages(pdu);
                                                    obj_bal_ForAll.bal_forAll_Delete("tbl_SMS", "smsId", dtObj.Rows[i]["smsId"].ToString());
                                                }
                                            }
                                        }
                                    }
                                    if (comm.IsOpen())
                                    {
                                        comm.Close();
                                    }  
                                    }catch(Exception ex){if (comm.IsOpen()){comm.Close();}}
Esmond answered 15/3, 2019 at 10:16 Comment(0)
C
0

If the Arduino IDE open close the IDE to release the port in the windows, the problem solved.

Cosset answered 19/12, 2023 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.