问题描述
这段时间在写一个串口程序,主要用于和设备进行通信,实现对设备状态的监测和控制。虽然软件编写是以串口的形式,但是设备是以USB形式连接到电脑的,USB接口一插接到电脑后,就映射成了一个COM口(也就是说在设备内部有个USB接口转串口的芯片,第一次连接电脑还要装驱动程序),所以写程序的时候完全不用管USB的事,使用串口的套路就行了。(本人电脑中已经有com1、com3口,所以映射成了com4口)软件做得差不多了,监测和控制的功能也完全能实现,但是突然发现有这么个问题,搞了很久也没有搞定!!问题是这样的:由于设备是连接到电脑USB接口的,所以存在随时拔掉该设备的情况。如果软件正在运行的时候,突然拔掉该USB,软件失去和设备的联系,监测和控制功能丧失,软件也不会报错,一切正常。但是,如果关闭软件,软件就会报错,在VS2005下提示“对端口的访问被拒绝”,而且报错不会定位到程序的任何一个代码行(这个最头疼,问题出在哪儿都不好找),关闭该报错提示窗口,软件窗口被关闭,但是程序仍然处于运行中,必须手动点击VS2005中停止按钮,程序才最终得到终止。为了解决这个问题,我在窗口的closing事件(窗口关闭前)过程中添加了serialport控件的close方法、给serialport控件的portname重新赋值为“com1”的方法、dispose释放serialport控件的方法,发现这些措施都不能避免软件报错,问题依旧。后来专门测试了下,在软件其他地方(不是窗口的closing过程中)使用完seriaport马上就进行关闭close,那么软件关闭不会报错。可问题是,这个软件运行的过程中随时要打开串口和设备进行通信,不可能关闭串口的,也就是说这个软件运行过程中,串口必须一直处于打开状态---关闭了就没法接受设备发送过来的信息了,就没法一直监控设备了。我现在能想到的唯一方法就是添加一个timer控件,以较高的频率(比如说10ms)不断地对计算机可用串口进行检测,当发现USB接口映射到那个com口不存在的时候,我就对serialport控件进行关闭或者重新赋值为其他com口,或者dispose该serialport控件,这种方法应该能解决该问题(虽然我还没有试过),但是我觉得这样有点浪费资源(timer控件一直处于打开状态),而且感觉方法稍微有点“笨拙”,呵呵,所以特发贴来此求助高人们,给一个最好的解决办法,知道这里高人多,望高人们不吝赐教啊!!!非常感谢了!!!谢谢!
解决方案
本帖最后由 anneall 于 2012-07-28 11:00:08 编辑
解决方案二:
顶起来等高手!!
解决方案三:
据传这是一个bug,微软至今未能修复。一些解决方案都包括部分或者全部使用WinAPI。
解决方案四:
关闭程序时,还会访问串口,但实际上已经拔掉了USB转串口线,导致提示错误“对端口的访问被拒绝”。http://blog.csdn.net/wuyazhe/article/details/5606276看看这篇文章,看看有没有帮助
解决方案五:
问题补充:我刚才试了下添加timer控件不断检测com口,然后或者关闭,或者重新赋值为其他com口,或者dispose,还是解决不了问题,软件关闭时仍然报错。。。。。。啊啊啊啊啊啊啊啊啊啊啊啊啊,555555,还以为这个方法可行呢,这下彻底没招了啊。巨期待高手。。。。。另外,我就纳闷了,使用timer控件监测串口,发现没了映射com口后,serialport就重新改变了,软件代码与映射端口毛关系没有了,怎么关闭还会报错?不是修改后与映射的那个com口都没有关系了吗想不通啊想不通,@高手,嘿嘿嘿
解决方案六:
不可能真的是微软的bug吧?晕啊。。。。。另外,三楼的哥们,可不可以在关闭的时候禁止软件访问串口?谢谢啦。。。。。
解决方案七:
弱弱地以为,可以试试DefWndProc(refMessagem)方法来监测插入或拔出PC的硬件,如果是你的设备,你就把它映射的COM口关掉。不确定的是,你插拔你的设备时,DefWndProc(refMessagem)方法是否能监测到。以下代码试试能否监测到你的设备:(如果插拔设备能,弹出了MessageBox,就说明能监测到;如果没弹出,就说明监测不到。)usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;namespaceTorquePcSoftware{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}inti=0;protectedoverridevoidDefWndProc(refMessagem){if(m.Msg==0x0219){i++;Console.WriteLine(i.ToString()+":"+m.ToString());MessageBox.Show(i.ToString()+":"+m.ToString());//deviceChangeDeal();}base.DefWndProc(refm);}}}第一次回答帖子,希望有帮助
解决方案八:
退出的时候,先try{serialPort1.BaseStream.Close();}catch(Exceptionex){MessageBox.Show(ex.ToString());}
这样就不会再抛出IOException了,亲测可行。
解决方案九:
在关闭串口时设置一个全局布尔变量代表正在关闭程序,这时DataRecieved事件里加上一句如果这个变量为真就return什么也不做,这样就不会再关闭程序时也去接收串口数据了。具体的代码在我给你的连接里。
解决方案十:
引用7楼的回复:
退出的时候,先C#codetry{serialPort1.BaseStream.Close();}catch(Exceptionex){MessageBox.Show(ex.ToString());}这样就不会再抛出IOException了,亲测可行。
这个方法不行啊,我试了,关闭时还是出错,出错提示一模一样
解决方案十一:
引用7楼的回复:
退出的时候,先C#codetry{serialPort1.BaseStream.Close();}catch(Exceptionex){MessageBox.Show(ex.ToString());}这样就不会再抛出IOException了,亲测可行。
这个方法不行啊,我试了,关闭时还是出错,出错提示一模一样
解决方案十二:
引用8楼的回复:
在关闭串口时设置一个全局布尔变量代表正在关闭程序,这时DataRecieved事件里加上一句如果这个变量为真就return什么也不做,这样就不会再关闭程序时也去接收串口数据了。具体的代码在我给你的连接里。
你提供的那篇文章我去年已经看过,是关于串口的一系列文章,当时认真研究了的,对串口编程帮助是非常地大。但是我觉得那篇文章只适用于打开/关闭串口时发生死锁的情况,但是我这个软件不是在打开、关闭时发生的错误,而是在使用完后,关闭软件时出错,具体情况如上面所述。或者是我没有理解到那篇文章的精髓???你能稍微再具体点吗??朋友,谢谢啦。。。。。。。。。。。。
解决方案十三:
我是楼主再次顶上,再次呼喊高手
解决方案十四:
系统有相对应的触发事件。不过这个事件也会有遗漏所有。果断用timer。没错USB监控平台。路过。
解决方案十五:
引用13楼的回复:
系统有相对应的触发事件。不过这个事件也会有遗漏所有。果断用timer。没错USB监控平台。路过。
今天上午用timer试了,还是那个问题,解决不了,详述在四楼。求大侠指教解决方法
解决方案:引用2楼的回复:
据传这是一个bug,微软至今未能修复。一些解决方案都包括部分或者全部使用WinAPI。
这不是一个传说,这是真实存在的BUG。解决方法很简单把对应的服务重起一下就好了。程序报错是正常的直接屏蔽掉。
解决方案:引用4楼的回复:
问题补充:我刚才试了下添加timer控件不断检测com口,然后或者关闭,或者重新赋值为其他com口,或者dispose,还是解决不了问题,软件关闭时仍然报错。。。。。。啊啊啊啊啊啊啊啊啊啊啊啊啊,555555,还以为这个方法可行呢,这下彻底没招了啊。巨期待高手。。。。。另外,我就纳闷了,使用timer控件监测串口,发现没了映射com口后,serialport就……
usb转串口。后台有个服务在运行。就算你拔掉了设备后台服务并不是立即或根本不会检测到。你的程序发的包只是发到了这个后台服务。再由这个服务转发。这个后台的服务并不健壮。并不会每时每刻都会去轮询设备还在不在。
其他方案:
usingSystem;usingSystem.IO;usingSystem.IO.Ports;usingSystem.Runtime.InteropServices;usingSystem.Text;usingMicrosoft.Win32.SafeHandles;namespaceSerialPortTester{publicclassSerialPortFixer:IDisposable{publicstaticvoidExecute(stringportName){using(newSerialPortFixer(portName)){}}#regionIDisposableMemberspublicvoidDispose(){if(m_Handle!=null){m_Handle.Close();m_Handle=null;}}#endregion#regionImplementationprivateconstintDcbFlagAbortOnError=14;privateconstintCommStateRetries=10;privateSafeFileHandlem_Handle;privateSerialPortFixer(stringportName){constintdwFlagsAndAttributes=0x40000000;constintdwAccess=unchecked((int)0xC0000000);if((portName==null)||!portName.StartsWith("COM",StringComparison.OrdinalIgnoreCase)){thrownewArgumentException("InvalidSerialPort","portName");}SafeFileHandlehFile=CreateFile(@"\."+portName,dwAccess,0,IntPtr.Zero,3,dwFlagsAndAttributes,IntPtr.Zero);if(hFile.IsInvalid){WinIoError();}try{intfileType=GetFileType(hFile);if((fileType!=2)&&(fileType!=0)){thrownewArgumentException("InvalidSerialPort","portName");}m_Handle=hFile;InitializeDcb();}catch{hFile.Close();m_Handle=null;throw;}}[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternintFormatMessage(intdwFlags,HandleReflpSource,intdwMessageId,intdwLanguageId,StringBuilderlpBuffer,intnSize,IntPtrarguments);[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternboolGetCommState(SafeFileHandlehFile,refDcblpDcb);[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternboolSetCommState(SafeFileHandlehFile,refDcblpDcb);[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternboolClearCommError(SafeFileHandlehFile,refintlpErrors,refComstatlpStat);[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternSafeFileHandleCreateFile(stringlpFileName,intdwDesiredAccess,intdwShareMode,IntPtrsecurityAttrs,intdwCreationDisposition,intdwFlagsAndAttributes,IntPtrhTemplateFile);[DllImport("kernel32.dll",SetLastError=true)]privatestaticexternintGetFileType(SafeFileHandlehFile);privatevoidInitializeDcb(){Dcbdcb=newDcb();GetCommStateNative(refdcb);dcb.Flags&=~(1u<<DcbFlagAbortOnError);SetCommStateNative(refdcb);}privatestaticstringGetMessage(interrorCode){StringBuilderlpBuffer=newStringBuilder(0x200);if(FormatMessage(0x3200,newHandleRef(null,IntPtr.Zero),errorCode,0,lpBuffer,lpBuffer.Capacity,IntPtr.Zero)!=0){returnlpBuffer.ToString();}return"UnknownError";}privatestaticintMakeHrFromErrorCode(interrorCode){return(int)(0x80070000|(uint)errorCode);}privatestaticvoidWinIoError(){interrorCode=Marshal.GetLastWin32Error();thrownewIOException(GetMessage(errorCode),MakeHrFromErrorCode(errorCode));}privatevoidGetCommStateNative(refDcblpDcb){intcommErrors=0;ComstatcomStat=newComstat();for(inti=0;i<CommStateRetries;i++){if(!ClearCommError(m_Handle,refcommErrors,refcomStat)){WinIoError();}if(GetCommState(m_Handle,reflpDcb)){break;}if(i==CommStateRetries-1){WinIoError();}}}privatevoidSetCommStateNative(refDcblpDcb){intcommErrors=0;ComstatcomStat=newComstat();for(inti=0;i<CommStateRetries;i++){if(!ClearCommError(m_Handle,refcommErrors,refcomStat)){WinIoError();}if(SetCommState(m_Handle,reflpDcb)){break;}if(i==CommStateRetries-1){WinIoError();}}}#regionNestedtype:COMSTAT[StructLayout(LayoutKind.Sequential)]privatestructComstat{publicreadonlyuintFlags;publicreadonlyuintcbInQue;publicreadonlyuintcbOutQue;}#endregion#regionNestedtype:DCB[StructLayout(LayoutKind.Sequential)]privatestructDcb{publicreadonlyuintDCBlength;publicreadonlyuintBaudRate;publicuintFlags;publicreadonlyushortwReserved;publicreadonlyushortXonLim;publicreadonlyushortXoffLim;publicreadonlybyteByteSize;publicreadonlybyteParity;publicreadonlybyteStopBits;publicreadonlybyteXonChar;publicreadonlybyteXoffChar;publicreadonlybyteErrorChar;publicreadonlybyteEofChar;publicreadonlybyteEvtChar;publicreadonlyushortwReserved1;}#endregion#endregion}}
源码来自blogpost地址就算了。在serialPort.Open();前加一句SerialPortTester.SerialPortFixer.Execute(Settings.Default.PortName);顺带我的系统是win764位,USB-串口是PL2303,框架版本是4.0ClientProfile
解决方案:在close事件加try{this.Dispose();}catch{}虽然不能解决你的报错根源问题。。。但报错还是不会提示的这个报错。估计是释放资源报错。也可能是线程出了问题报错。总之。如果多线程没管理好的话。或者辅助线程接触到UI线程也会可能报类似的错误。。。这个是原理和结构问题。。。试试看能不能解决眼前的问题
解决方案:引用17楼的回复:
加一段代码(一个单独类,调用静态方法):C#codeusingSystem;usingSystem.IO;usingSystem.IO.Ports;usingSystem.Runtime.InteropServices;usingSystem.Text;usingMicrosoft.Win32.SafeHandles;namespaceSerialPort……
虽然代码都看不懂,但是还是照做了,可是也不行啊——照着敲这么多代码,好累啊,呵呵iyomumx,可以提供你的QQ吗,请教一下,这问题真的困着我了
解决方案:引用18楼的回复:
在close事件加try{this.Dispose();}catch{}虽然不能解决你的报错根源问题。。。但报错还是不会提示的这个报错。估计是释放资源报错。也可能是线程出了问题报错。总之。如果多线程没管理好的话。或者辅助线程接触到UI线程也会可能报类似的错误。。。这个是原理和结构问题。。。试试看能不能解决眼前的问题
在窗体的closing事件中已经加了你说的方法,关闭程序仍然报错,现象一模一样。注意∶报错时不会定位到如何一行代码,晕死,这样的不错第一次碰到,好头疼
解决方案:再次回复求助。期待更多朋友给予我指点软件都做完了,就剩下这么个问题困扰我,叫同事也看了,也是束手无策,只是建议我不用serialport控件,改用api函数实现,晕,那个我也是差不多门外汉,工作量也大,而且能不能解决这样的问题也暂不知道。。求助大神,再次拜谢大神们,请支支招,万分感谢。。。。。。。。。。。
解决方案:VS03的时候没有serialport类都是用API的嘛姑且试试吧网上现成源码无非替换下不过有可能一样会报错还有一个办法是在串口关闭前重启后台服务
解决方案:引用22楼的回复:
VS03的时候没有serialport类都是用API的嘛姑且试试吧网上现成源码无非替换下不过有可能一样会报错还有一个办法是在串口关闭前重启后台服务
怎么重启啊?求指教。。。。。。
解决方案:ServiceController[]slist=ServiceController.GetDevices();foreach(ServiceControllerserviceinslist){if(service.ServiceName=="服务名"){service.Stop();service.Start();}}
解决方案:我用的USB虚拟的串口软件(或者RJ45虚拟的),在DELPHI中也碰到过类似问题,在WinApi层好象CreateHandle()、PurgeComm()等出错,没仔细研究,我是在上层就把错误屏蔽了
解决方案:由于设备是连接到电脑USB接口的,所以存在随时拔掉该设备的情况。如果软件正在运行的时候,突然拔掉该USB,软件失去和设备的联系,监测和控制功能丧失,软件也不会报错,一切正常。但是,如果关闭软件,软件就会报错,在VS2005下提示“对端口的访问被拒绝”,而且报错不会定位到程序的任何一个代码行(这个最头疼,问题出在哪儿都不好找),关闭该报错提示窗口,软件窗口被关闭,但是程序仍然处于运行中,必须手动点击VS2005中停止按钮,程序才最终得到终止。从这两个红色标注的地方,可以猜测LZ应该是用的多线程。第一个标注红色地方:猜测你的程序不会报错是因为你catch住不处理,但是还是一直在发送数据。第二个标注红色地方:你的程序界面关闭,但是还在运行。这说明你的多线程应该没有IsBackground=true;导致程序退出时没有关闭线程。你试着把Thread的IsBackground设为true看看。
解决方案:再次顶上,期待高手们的光临指导!这次附上问题程序的源代码工程(VS2005下编译的):下载:http://115.com/file/e704quat#或者:http://163.fm/IFzgf2L提取码:LucGDi3Q(163邮箱的网盘)问题程序源代码:privatevoidForm1_Load(objectsender,EventArgse){serialPort1.Close();serialPort1.BaudRate=9600;serialPort1.DataBits=8;serialPort1.StopBits=StopBits.One;serialPort1.Parity=Parity.None;serialPort1.PortName="COM4";//USB转串口映射的串口号为com4serialPort1.Open();}privatevoidbutton1_Click(objectsender,EventArgse)//发送数据到设备{byte[]bytWrite=newbyte[]{0xe1,0xee,0xee,0xee,0x30};//byte数组try{if(!serialPort1.IsOpen)serialPort1.Open();serialPort1.Write(bytWrite,0,bytWrite.Length);}catch(Exceptionex){MessageBox.Show(ex.ToString());serialPort1.Close();serialPort1.Dispose();}}privatevoidserialPort1_DataReceived(objectsender,SerialDataReceivedEventArgse)//从串口接收数据{intn=serialPort1.BytesToRead;byte[]buf=newbyte[n];serialPort1.Read(buf,0,n);Console.WriteLine("当前串口收到数据:"+BitConverter.ToString(buf));}privatevoidForm1_FormClosing(objectsender,FormClosingEventArgse){serialPort1.Close();//窗体关闭前关闭串口serialPort1.Dispose();//窗体关闭前释放串口}
另外,我发现了用很多网络上下载的串口调试程序进行调试的时候,很多串口调试软件也存在这个问题,当USB拔掉后,关闭软件出错,而且有些软件根本就关不掉,一直弹出出错提示,看来这个问题还是普遍存在啊,相当多的程序员在写串口程序的时候,都忽略了这个问题。因为平常的情况下,com口在软件运行过程中都是一直存在的,刚好这次我写程序遇到usb转串口这样的情况,调试软件时才发现了这个问题。呵呵。。。。。。但是,也不是所有的串口调试软件在这种情况下都会出错,现目前我发现一个叫做UartAssist.exe的串口调试软件在遇到这种情况的时候不会出错,关闭软件一切正常,呵呵,看来这个问题还是能够避免的,就是我才疏学浅还没有掌握到,所以特地再来此顶贴,希望高手们都来看看,不要忽略了这个问题。小弟不胜感谢!!!
解决方案:引用26楼的回复:
由于设备是连接到电脑USB接口的,所以存在随时拔掉该设备的情况。如果软件正在运行的时候,突然拔掉该USB,软件失去和设备的联系,监测和控制功能丧失,软件也不会报错,一切正常。但是,如果关闭软件,软件就会报错,在VS2005下提示“对端口的访问被拒绝”,而且报错不会定位到程序的任何一个代码行(这个最头疼,问题出在哪儿都不好找),关闭该报错提示窗口,软件窗口被关闭,但是程序仍然处于运行中,必须手动点击……
源代码已经贴上,能给出具体的处理代码吗???谢谢
解决方案:进来顶一下,巨期待高手。。。。。。。。。。。。。。
解决方案:该回复于2012-08-06 15:13:41被版主删除
解决方案:该回复于2012-08-06 16:02:17被版主删除
解决方案:我是楼主,换了个ID,进来顶一下期待问题得到解决啊。我哭死。。。。。。。。。。。
解决方案:退出前检测下刚才打开得串口是否还存在或者处于打开状态,不存在直接退出,存在则关闭并且释放
解决方案:引用33楼的回复:
退出前检测下刚才打开得串口是否还存在或者处于打开状态,不存在直接退出,存在则关闭并且释放
考虑过,并测试了,结果无用
解决方案:退出前检测下刚才打开得串口是否还存在或者处于打开状态,不存在直接退出,存在则关闭并且释放上面这个方法你试了?不行?我觉得这种是可行的,意外拔掉USB,系统就找不到那个串口,所以那个时候关闭是会出错的,你在关之前自己动查找下COM口是,是不是和打开的COM相同,有就正常关闭,没有就直接退出。
解决方案:引用35楼的回复:
退出前检测下刚才打开得串口是否还存在或者处于打开状态,不存在直接退出,存在则关闭并且释放上面这个方法你试了?不行?我觉得这种是可行的,意外拔掉USB,系统就找不到那个串口,所以那个时候关闭是会出错的,你在关之前自己动查找下COM口是,是不是和打开的COM相同,有就正常关闭,没有就直接退出。
这个方法是不行的,已经试了。软件故障现象是:拔掉usb接口后,即使在关闭软件之前再次插上usb线缆,关闭时也会报错。总之,软件运行过程中只要有拔掉usb线缆,之后任何情况软件关闭都会出错,也就是说即使那个com口还存在,依然报错。。。。痛苦,现在还没有找到解决方法。
解决方案:LZ你好,我自己测试没有向串口写入数据,应该是这个原因不能重现这个问题。你可以考虑对AppDomain.Current.UnhandledException事件注册处理程序,在这里应该可以捕捉到错误,并能通过设置UnhandledExceptionEventArgs.ExitApplication来保证应用程序正常退出。
解决方案:建议选用波仕电子的型号为USB232ET的USB网络串口转换器,内部使用的是TCP/IP协议,也可以虚拟成为串口,使用SOCKET控件代替串口通信控件这样就自然解决了这个问题。
解决方案:楼主,你好,你的问题解决了么?我现在也遇到相同的问题,很是棘手啊,大家有没有好办法,顶起来啊
解决方案:引用39楼juanjuan526502的回复:
楼主,你好,你的问题解决了么?我现在也遇到相同的问题,很是棘手啊,大家有没有好办法,顶起来啊
没有彻底解决,呵呵,头疼
解决方案:我写的也一直存在相似问题,若串口处于打开状态时直接拨掉后,再重新插入串口就不能用了,除非把软件关闭再打开才可以。很是郁闷,这问题缠了我一年多了。无奈好像用serialport组件的人太少了!
解决方案:这个问题不好整,你看看串口调试助手,都是拔掉串口后程序出错连结束都不让点。我们经常用串口一样的毛病,串口故障了,软件反应的是数据没获得。你去用软件解决这个问题,为什么不保持你的串口不变动呢?USB转串口我们都是笔记本临时调试用,就这还有时候会罢工呢,不用说用到成品软件上了。
解决方案:"如果软件正在运行的时候,突然拔掉该USB,软件失去和设备的联系,监测和控制功能丧失,软件也不会报错,一切正常。但是,如果关闭软件,软件就会报错,在VS2005下提示“对端口的访问被拒绝”,而且报错不会定位到程序的任何一个代码行(这个最头疼,问题出在哪儿都不好找)"==================拔掉USB不会出错是因为串口没有数据,不会触发DataReceived事件,此过程中没有对端口进行操作。但是关闭窗体的时候,是要释放串口资源的,于是就出错了。没想到什么好的办法,试试在关闭窗口的时候直接退出程序“Environment.Exit(0);"
解决方案:这个问题的根源就是出在微软,因为打开一个串口,相当于打开一个文件,在微软认为,打开的文件是无法被删除的。但是,出现了USB转串口之后,这个问题就出现了,即使打开一个串口,仍然可以强制拔掉USB线,这样,打开的文件就不存在了,那么就会出现楼主的问题,暂时没有想到解决办法
解决方案:这问题解决了吗
解决方案:木有检测设备状态的接口吗用个线程监控设备状态
其他方案:
https://connect.microsoft.com/VisualStudio/feedback/details/140018/serialport-crashes-after-disconnect-of-usb-com-port
解决方案:没什么办法,亲测,即使拔掉USB,IsOpend属性依然为true这样在执行close的时候一定会出错
解决方案:使用.net4.0应该不会有下面的问题引用48楼Z65443344的回复:
没什么办法,亲测,即使拔掉USB,IsOpend属性依然为true这样在执行close的时候一定会出错
解决方案:引用49楼pengwu666的回复:
使用.net4.0应该不会有下面的问题Quote: 引用48楼Z65443344的回复:
没什么办法,亲测,即使拔掉USB,IsOpend属性依然为true这样在执行close的时候一定会出错
4.0修复了这个BUG?测试过吗,不要靠猜想