使用Device.Net的Observable.FromAsync出现内存泄漏问题求助
基于Device.Net库的HID轮询内存泄漏问题及解决办法
问题背景
基于MelbourneDeveloper/Device.Net库的HID示例修改后,通过每100ms轮询HID设备,搭配TransferResult(byte[] data, uint bytesRead)回调处理数据。经DotMemory检测,每次调用返回的TransferResult存在内存泄漏。
泄漏复现代码
_hidObserver = Observable .Interval(TimeSpan.FromMilliseconds(1000)) .SelectMany(_ => Observable.FromAsync(() => _hidIDevice.ReadAsync())) .DefaultIfEmpty() .Subscribe(onNext: tuple => { Console.WriteLine("QUEUE | bytes transferred: " + tuple.BytesTransferred); Console.WriteLine("QUEUE | bytes: " + tuple.Data); return; }, onCompleted: () => Console.WriteLine("HID Button Observer | Completed."), onError: exception => Console.WriteLine($"HID Button Observer | Error | {exception.Message}.") );
内存泄漏表现
应用初始内存占用70MB,运行17小时后内存增至1.8GB;注释掉Observable相关代码后,内存保持稳定无增长。
问题排查与解决
初步优化
应用相关建议解决了部分内存泄漏,但仍有残留。进一步分析确认,泄漏根源在Device.Net库内部实现。
库内部问题点
库中调用Windows HID API时存在错误:
private static extern bool HidD_FreePreparsedData(ref IntPtr pointerToPreparsedData); isSuccess = HidD_FreePreparsedData(ref pointerToPreParsedData);
根据微软官方文档,调用HidD_FreePreparsedData时不应使用ref关键字,否则无法正确释放预解析数据句柄,进而导致内存泄漏。
修复方案
修改库中对应代码,移除ref关键字:
private static extern bool HidD_FreePreparsedData(IntPtr pointerToPreparsedData); isSuccess = HidD_FreePreparsedData(pointerToPreParsedData);
通过fork该库并修改上述两行代码后,内存泄漏问题彻底解决。
内容的提问来源于stack exchange,提问作者iceman2894
相关产品推荐
相关产品推荐

