我有一個C程序,它打開一個COM端口的句柄,向它寫入一些字節,讀出一些字節,然後關閉句柄並退出。但是,當我連續運行10次程序時,開始花費很長時間才能完成GetCommState
函數,並陷入SetCommState
函數中。 C#中同樣的事情發生在一個簡單的SerialPort
對象中。使用usbser.sys凍結SerialPort.Open/DeviceIoControl/GetcommState
我能找到的唯一修復方法是將設備重新連接到端口。有沒有更好的方法來擺脫這種凍結?這可能只是一些電腦配置錯誤?
我已經重寫代碼更新,以使其使用DeviceIoControl
代替SetCommState
。但是,這裏的問題完全相同。
device =
CreateFileW(
L"\\\\.\\COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
static int SetBaudRate (HANDLE device) {
int error = 0;
int success = 0;
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(NULL, TRUE, 0, NULL);
if (overlapped.hEvent) {
SERIAL_BAUD_RATE baudRate = {0};
baudRate.BaudRate = SERIAL_BAUD_115200;
error =
DeviceIoControl(
device, IOCTL_SERIAL_SET_BAUD_RATE, &baudRate,
sizeof(SERIAL_BAUD_RATE), NULL, 0, NULL, &overlapped);
if (error || (!error && GetLastError() == ERROR_IO_PENDING)) {
DWORD bytes = 0;
if (GetOverlappedResult(device, &overlapped, &bytes, TRUE)) {
success = 1;
}
}
}
CloseHandle(overlapped.hEvent);
return success;
}
第一個問題:DeviceIoControl
不會立即返回(雖然異步調用),並掛起了大約兩分鐘。 第二個問題:在這兩分鐘後,它會失敗,並顯示錯誤代碼121(ERR_SEM_TIMEOUT:「信號量超時期已過。」)。
- 所使用的驅動程序是標準的Windows驅動程序
usbser.sys
- 爲什麼函數調用不立即返回任何想法?如果沒有,如何設置一個更短的超時功能?
- 關於爲什麼函數失敗的任何想法?
更新2
樣品C#這也凍結(如上面的C程序)碼:
using System;
using System.IO.Ports;
sealed class Program {
static void Main (string[] args) {
int i = 0;
while (true) {
Console.WriteLine(++i);
SerialPort p =
new SerialPort("com3", 115200, Parity.None, 8, StopBits.One);
p.DtrEnable = true;
p.RtsEnable = true;
p.ParityReplace = 0;
p.WriteTimeout = 10000;
p.ReadTimeout = 3000;
try {
p.Open();
Console.WriteLine("Success!");
} catch (Exception e) {
Console.WriteLine(e.GetType().Name + ": " + e.Message);
}
p.Close();
Console.ReadLine();
}
}
}
樣品輸出如下:
1 (device not yet connected)
IOException: The port 'com3' does not exist.
2 (device connected but not yet in windows device manager)
IOException: The port 'com3' does not exist.
3
IOException: The port 'com3' does not exist.
4 (device connected and recognized)
Success!
5
Success!
[...] (with about one second between each enter press)
15
Success!
16 (device still connected and recognized - nothing touched! after two minutes of freeze, semaphore timeout exactly as in the C version)
IOException: The semaphore timeout period has expired.
17 (device disconnected during the two minutes of freeze. it then returns instantly)
IOException: A device attached to the system is not functioning.
18 (device still disconnected - note that the exception is a different one than the one in the beginning although it's the same case: device not connected)
IOException: The specified port does not exist.
19
IOException: The port 'com3' does not exist.
當你說它「凍結系統」是「系統」只是你的程序或整個計算機? – Gabe
只是程序。當我用調試器遍歷代碼時,GetCommState會在1分鐘後返回,並且SetCommState需要更長的時間,直到由於超時而失敗。 – Etan
這是一個內置的串行端口,虛擬端口,USB串行端口或其他? – Gabe