Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SerialPort The Requested Resource is in Use (both .net core and .net framework) #39464

Open
chenxuuu opened this issue Jul 14, 2019 · 18 comments
Open
Milestone

Comments

@chenxuuu
Copy link

@chenxuuu chenxuuu commented Jul 14, 2019

I use this code:

using System;
using System.IO.Ports;
using System.Threading.Tasks;

namespace sp
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort();
            port.PortName = "COM3";
            while (true)
            {
                Console.WriteLine($"port open: {port.IsOpen}");
                if (!port.IsOpen)
                {
                    foreach (var i in SerialPort.GetPortNames())
                    {
                        Console.WriteLine($"scan port {i}");
                        if (i == port.PortName)
                            try
                            {
                                port.Open();
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine($"error: {e}");
                            }
                    }
                }
                Task.Delay(1000).Wait();
            }
        }
    }
}

I run this code, connect my 4GLTE device and srart it, the code connect success

but, if I restart my 4GLTE device(not disconnect, only press restart button, this COM will disappear in Device Manager), it will show an error message: The Requested Resource is in Use, and not disappear in serial port list.

when my device is restart ok, it will still report this error, until I close my program and rerun.

this bug is also in .net framework, same code.(I tried to report this, but nobody reply me)

code logs:

port open: False
port open: False
scan port COM3
scan port COM4
scan port COM5
port open: True
port open: True
port open: True
port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24
port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24

************some same logs**************

port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24

************* device restart complete here **************

port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24
scan port COM4
scan port COM5
port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24
scan port COM4
scan port COM5
port open: False
scan port COM3
error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in C:\Users\chenx\Desktop\sp\sp\Program.cs:line 24
scan port COM4
scan port COM5

************same logs forever**************

more infomation:

  1. I tried many different device, only this 4GLTE device will show this problem
  2. I tried many different serial port debug tools, I found that all of tools written in C# will show this problem, other written in cpp or python are all normal
  3. Same problem in .net framework (I tested on .net framework 4.7.2 and .net core 2.1)

is this my wrong usage?

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 14, 2019

sp.zip
my test project

@stephentoub stephentoub added this to the Future milestone Jul 14, 2019
@stephentoub

This comment has been minimized.

Copy link
Member

@stephentoub stephentoub commented Jul 14, 2019

cc: @krwq

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Jul 14, 2019

@chenxuuu, inside of the try..catch which reopens could you replace port.Open(); with

port.Dispose();
port = new SerialPort();
port.PortName = "COM3";
port.Open();

and see if that workarounds the problem?

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 15, 2019

@krwq not work, same problem.
also, I have tried port.Dispose() and port.BreakState = false two weeks ago.

more infomation:
this device use a driver without signature, I need to disable driver signature enforcement.
when this device start complete, it will provide 3 virtual serial ports.

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Jul 15, 2019

@chenxuuu interesting, I'd expect disposing and re-creating it to solve this. Are you sure you didn't skip port = new SerialPort(); after Dispose when you've tried it 2 weeks ago? Could you also try Disposing port.BaseStream before disposing port and see if that makes any difference?

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 16, 2019

dosen't work😕

my new code and logs:

using System;
using System.IO.Ports;
using System.Threading.Tasks;

namespace sp
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort();
            port.PortName = "COM4";

            while (true)
            {
                Console.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss:ffff]")}port open: {port.IsOpen}");
                if (!port.IsOpen)
                {
                    foreach (var i in SerialPort.GetPortNames())
                    {
                        Console.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss:ffff]")}scan port {i}");
                        if (i == port.PortName)
                            try
                            {
                                try
                                {
                                    port.BaseStream.Dispose();
                                }
                                catch(Exception ex)
                                {
                                    Console.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss:ffff]")}BaseStream: {ex}");
                                }
                                port.Dispose();
                                port = new SerialPort();
                                port.PortName = "COM4";
                                port.Open();
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss:ffff]")}error: {e}");
                            }
                    }
                }
                Task.Delay(1000).Wait();
            }
        }
    }
}
[2019-07-16 10:17:42:9674]port open: False
[2019-07-16 10:17:43:0669]scan port COM4     /*************  open success  *************/
[2019-07-16 10:17:43:0965]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:17:43:2723]scan port COM5
[2019-07-16 10:17:43:2725]scan port COM6
[2019-07-16 10:17:44:2824]port open: True
[2019-07-16 10:17:45:2891]port open: True
[2019-07-16 10:17:46:2901]port open: True
[2019-07-16 10:17:47:2911]port open: True
[2019-07-16 10:17:48:2927]port open: True
[2019-07-16 10:17:49:2935]port open: True

/*************  I restart device here, all ports disappeared in Device Manager  *************/

[2019-07-16 10:17:50:2955]port open: False
[2019-07-16 10:17:50:2959]scan port COM4
[2019-07-16 10:17:50:3129]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:17:50:3619]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36
[2019-07-16 10:17:51:3659]port open: False
[2019-07-16 10:17:51:3663]scan port COM4
[2019-07-16 10:17:51:3822]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:17:51:3998]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36

/*************  same logs, skip  *************/

[2019-07-16 10:17:52:4069]port open: False
[2019-07-16 10:17:52:4074]scan port COM4
[2019-07-16 10:17:52:4267]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:17:52:4453]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36

/*************  device boot complete, 3 ports appeared in Device Manager  *************/

[2019-07-16 10:18:07:0075]port open: False
[2019-07-16 10:18:07:0079]scan port COM4
[2019-07-16 10:18:07:0366]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:18:07:0640]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36
[2019-07-16 10:18:07:0703]scan port COM5
[2019-07-16 10:18:07:0720]scan port COM6
[2019-07-16 10:18:08:0747]port open: False
[2019-07-16 10:18:08:0755]scan port COM4
[2019-07-16 10:18:08:1209]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:18:08:1468]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36
[2019-07-16 10:18:08:1537]scan port COM5
[2019-07-16 10:18:08:1568]scan port COM6

/*************  same logs, skip  *************/

[2019-07-16 10:18:14:3647]port open: False
[2019-07-16 10:18:14:3652]scan port COM4
[2019-07-16 10:18:14:3826]BaseStream: System.InvalidOperationException: The BaseStream is only available when the port is open.
   at System.IO.Ports.SerialPort.get_BaseStream()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 27
[2019-07-16 10:18:14:3988]error: System.IO.IOException: 请求的资源在使用中。
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
   at System.IO.Ports.SerialPort.Open()
   at sp.Program.Main(String[] args) in D:\OneDrive\同步文件夹\luat_desktop\sp\sp\Program.cs:line 36
[2019-07-16 10:18:14:4014]scan port COM5
[2019-07-16 10:18:14:4019]scan port COM6

C:\Program Files\dotnet\dotnet.exe (进程 11744)已退出,返回代码为: -1。
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...
@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 17, 2019

need I mail a device for testing?

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Jul 17, 2019

@chenxuuu, I don't think that will be necessary

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 22, 2019

need I do some other tests?

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Jul 22, 2019

@chenxuuu what kind of serial port are you using? (i.e. usb/uart/physical com port). It would be interesting to inspect the process with i.e. Process Explorer and see what kind of file handles are open while this is happening - we are very likely not disposing something in the code.

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Jul 23, 2019

@krwq A 4G module,with 3 serial ports from 1 usb.
I record a screen video: https://1drv.ms/v/s!Asz6jM0Kmex1p8wRA1P9Fakx9qvOvw?e=DV2fRt

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Sep 3, 2019

any solution?

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Sep 3, 2019

@chenxuuu unfortunately I'm unable to reproduce this. I've run the repro re-plugged my device several times and works as expected.

I think this might be an issue with your device (or driver). Perhaps the driver reports it too quickly as available...

One thing you can try is to perhaps when opening a port fails add some delay and retry couple of times before declaring it failed - this is not fixing the problem but at least might workaround it.

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Sep 4, 2019

can't reopen those port, Dispose is useless, unless restart program.

my 4g module is based on ASR1802s(Air720).
this bug also happends on my another 4g module based on Qualcomm MDM9207(U9300C).

all device work's well with c/cpp codes.
all tools wroten by c# have this problem (I find them on internet, not wroten by me).

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Sep 4, 2019

@chenxuuu could you share the C/C++ code you are using and works for you for reference? Also could you point me to somewhere where I can get the specific device you're seeing the problem with? (i.e. amazon/aliexpress link).

Also what version of System.IO.Ports package are you using?

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Sep 5, 2019

my cpp code:

// ConsoleApplication1.cpp
//

#include <iostream>
#include <windows.h>
using namespace std;
HANDLE hMutex;

DWORD WINAPI Read(LPVOID lpParamter)
{
	while (1)
	{
		//open port
		HANDLE hCom = CreateFileA("com4", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
		//set timeout
		COMMTIMEOUTS timeouts;
		GetCommTimeouts(hCom, &timeouts);
		timeouts.ReadIntervalTimeout = 0;
		timeouts.ReadTotalTimeoutMultiplier = 0;
		timeouts.ReadTotalTimeoutConstant = 1;
		timeouts.WriteTotalTimeoutMultiplier = 0;
		timeouts.WriteTotalTimeoutConstant = 0;
		if (!SetCommTimeouts(hCom, &timeouts))
		{
			cout << "timeout" << endl;
			CloseHandle(hCom);
			Sleep(5000);
			continue;
		}

		//get port state
		DCB dcb;
		GetCommState(hCom, &dcb);
		dcb.DCBlength = sizeof(DCB);
		dcb.BaudRate = 9600;
		dcb.Parity = 0;
		dcb.ByteSize = 8;
		dcb.StopBits = ONESTOPBIT;
		if (!SetCommState(hCom, &dcb))
		{
			cout << "open fail" << endl;
			CloseHandle(hCom);
			Sleep(5000);
			continue;
		}

		cout << "open success" << endl;

		char buffer[1024];
		DWORD readsize, dwError;
		BOOL bReadStatus;
		COMSTAT cs;

		WaitForSingleObject(hMutex, INFINITE);
		while (1)
		{
			readsize = 0;
			ClearCommError(hCom, &dwError, &cs);//get port state
			if (dwError != 0)
			{
				cout << "uart error: " << dwError << endl;
				break;
			}
			Sleep(5);
		}
		ReleaseMutex(hMutex);
		CloseHandle(hCom);
		cout << "uart closed" << endl;
		Sleep(1000);
	}
}

void main(void)
{
	HANDLE hThread = CreateThread(NULL, 0, Read, NULL, 0, NULL);
	hMutex = CreateMutex(NULL, FALSE, NULL);
	CloseHandle(hThread);
	while (1)
		Sleep(1000);
}

outpot:

open success
uart error: 31      <====I restart my device here
uart closed
timeout
timeout
timeout
timeout
open success    <====device boot complete

Air720 board can be found on aliexpress and taobao
https://www.aliexpress.com/item/4000097129001.html
https://item.taobao.com/item.htm?id=588424557201


I tested c# codes with vs2019's default .net core 2.1 and .net framework 4.7.2

@chenxuuu

This comment has been minimized.

Copy link
Author

@chenxuuu chenxuuu commented Nov 6, 2019

any progress?
I want to test this c# code on linux, maybe not same as windows

@krwq

This comment has been minimized.

Copy link
Member

@krwq krwq commented Nov 6, 2019

@chenxuuu unfortunately I haven't had time to take a look at this yet. To make progress here it might be worth if you can find the diff between your C++ code vs what we do in our implementation and we can decide what to do from there.

Also as you mentioned you might want to check the Linux since the code is different enough the issue might not be present there (if that is an acceptable workaround for you).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.