问题标签 [safehandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1689 浏览

c# - 使用 FileStream.SafeFileHandle 后,删除对 GC.KeepAlive() 的调用是否安全?

考虑以下我最近更改为使用的代码FileStream.SafeFileHandle

我之前添加了以确保在 Windows API调用返回GC.KeepAlive(fs)之前不会对 FileStream 进行垃圾收集。WriteFile()

但是,在更改为使用SafeFileHandle代码分析后,现在告诉我没有必要使用warning CA2004: Remove calls to GC.KeepAlive

如果要转换为 SafeHandle 用法,请删除对 GC.KeepAlive(对象)的所有调用。

我已经查阅了文档,FileStream.SafeFileHandle但我不清楚删除对GC.KeepAlive().

删除它绝对安全吗?我是否正确使用它?

另外,任何人都可以指出一些关于使用 SafeHandle 的体面文档吗?

0 投票
2 回答
299 浏览

c# - SafeHandle 中 invalidHandleValue 的作用是什么?

构造SafeHandle函数接受一个invalidHandleValue. 如果IsInvalid无论如何都必须实施,它有什么用因为它不知道哪个成员变量持有指针[我不知道它handle为你实现了成员变量]?

0 投票
4 回答
30274 浏览

c# - ObjectDisposedException:安全句柄已关闭

所以这是一个很小的问题,但有很大的解释。正如标题所指出的,我收到一个未处理的异常,告诉我我的安全句柄已关闭。我可能需要做的是用越来越多的代码编辑这篇文章几次,以帮助我诊断问题所在。

我正在使用 POS for .NET 为我的 RFID 和 MSR 设备制作服务对象。虽然我的设备是相同的,但我有 2 个不同的虚拟 COM 端口芯片可以与这些设备通信。一个来自 Silicon labs,另一个来自 FTDI。我想使用 POS for .NET 的即插即用功能,所以我给了它我的硬件 ID。因为它是即插即用的,所以我可以使用完整的硬件路径,然后我可以使用对 PInvoke 的调用创建一个 SafeFileHandle,并使用该 SafeFileHandle 创建一个 FileStream。FTDI 芯片不允许我像那样直接与设备通信,所以我必须获取设备的友好名称,然后使用互斥锁来拉出 COM 端口,然后创建一个 SerialPort 实例。这一步效果很好。作为仅供参考,我尝试使用两种芯片的友好名称来获取 COM 端口,而 Silicon Labs 的一个(出于某种奇怪的原因)没有使用 SetupAPI.GetDeviceDetails 使用 Ports GUID 列出。我不确定那个,因为在设备管理器中,Silicon labs Device Class Guid 是端口 GUID。

好吧,由于 SerialPort 和 FileStream 都有一个 Stream 对象,我决定使用它来读取和写入该端口。问题在于,如果我向 MSR 设备发送 RFID 命令,则 MSR 设备不会回复任何内容。因此,如果我使用此代码,int fromReader = ReaderStream.ReadByte();我的线程将被阻止。这是一个阻塞调用,至少需要 1 个字节才能继续。所以我环顾四周,似乎唯一的解决方案是使用单独的线程并设置超时。如果发生超时,则中止线程。

(t.Abort 被 try/catch 包围无济于事,因为它没有解决我删除它的问题)

ReadFromStream 是 RFID 设备中的抽象方法。这是其中一种实现

int fromReader = ReaderStream.ReadByte();被 try/catch 包围。它唯一捕获的就是中止的线程异常,所以我把它拿出来了)

上面的代码是我怀疑问题所在。不过,奇怪的是,我有一个单元测试,我觉得它很好地模仿了 Microsoft 测试应用程序。

(仅供参考 QUADPORT 是 FTDI 芯片组)

当我运行该测试时,我没有收到 SafeFileHandle 异常。事实上测试通过了。

所以我不知道如何追踪这个错误。由于我将在我也在创建的另一个程序中使用此服务对象,因此我可能最终会在该程序中使用此测试中的此代码。但是我觉得微软测试应用程序或多或少是“黄金标准”。真的吗……应该不会吧。但它确实对我的目的有用,所以我觉得这是我的代码问题,而不是他们的问题。

关于如何缩小范围的任何技巧?仅供参考,我尝试使用调试器,但在打开代码中不会发生错误。我还走过了更新状态计时器,它也没有抛出错误。一旦我点击继续,我就会得到异常。我打开了只是我的代码和加载的符号,它告诉我“此模块的调试信息中缺少源信息”

0 投票
1 回答
160 浏览

f# - 在 F# 中使用 SafeHandles

我正在使用一些使用平台调用的 F# 代码。我正在使用的 API 之一返回一个句柄。nativeint我没有使用 ,而是实现了自己的 SafeHandle(特别是SafeHandleMinusOneIsInvalid.)。这使得使用包含 pinvoke 签名的模块有点笨拙。这是一个例子:

这不会编译,因为模块和类递归地相互引用,这是行不通的。如果我将模块移到上面MySafeHandle,则GetHandle看不到 SafeHandle。

我无法将平台调用方法移到内部,MySafeHandle因为 F# 中的外部方法似乎必须在模块中(即使编译器不会阻止您尝试将它们放入类中)。

似乎 F# 的递归类型在模块和类之间不起作用,只是在类之间起作用。

这个问题有没有不需要声明两个不同模块的解决方案?理想情况下,我希望将我的所有平台调用代码组织到一个模块中。

0 投票
1 回答
796 浏览

c# - 如何正确处理 pinvoke/非托管代码

我有需要 pinvoke ac dll 的代码,在我看来,这段代码应该实现 idisposible,因为它涉及非托管代码。我可能是错的,所以如果这不是真的,请纠正我。

阅读这些东西似乎我应该使用安全手柄。伟大的。除了我的 dll 不返回任何句柄或 intptr。那么现在怎么办?

签名大多如下:

参数值:

pTripID:指向一个 4 字节整数的指针,新的行程句柄将被放置在其中

我可以在里面塞一个安全把手吗?从这篇文章看来,这可能是个难题。

0 投票
1 回答
120 浏览

c# - 使用 SafeHandle 的约束与抽象类

BCryptNative 中有一个名为GetInt32Property的方法。它具有以下签名:

此方法仅在 T 类型为SafeBCryptAlgorithmHandleSafeBCryptHashHandle时有效。它调用使用这些类型的句柄显式定义的本机方法:

Microsoft 使用函数指针/委托来指向正确的本机函数。我的问题是,为什么微软不使用以下签名实现 GetInt32Property 方法:

使用以下本机方法:

这有什么缺点吗?(假设传递给 GetInt32Property 的 SafeHandle 始终是SafeBCryptAlgorithmHandleSafeBCryptHashHandle)。

我只是想知道为什么微软实现这个相对复杂。

是否必须:

  • 安全透明代码?
  • 类型安全?(这样您就永远不会使用这两种类型之外的任何其他类型)
  • 是否允许明确使用 SafeHandle?

根据文档,该类必须被继承,但是当给定 SafeHandle 的抽象类时,P/Invoked 函数是否正确处理它?它是否适当地增加和减少引用计数?

0 投票
1 回答
540 浏览

c# - 编组 Win32 结构时的安全句柄 (PROCESS_INFORMATION)

我正在将我的 Win32 p/invoke 代码转换为使用SafeHandle类而不是典型的IntPtr句柄。

虽然在方法签名中一切都很好DllImport,但我无法在编组 Win32 结构(即PROCESS_INFORMATION)时让它们工作。

ProcessSafeHandleandThreadSafeHandle类与ReadProcessMemoryor之类的方法一起工作得很好WriteProcessMemory,但我不能在上面的 Win32 结构中使用它们。

我是否缺少某种注释魔术?

0 投票
2 回答
1941 浏览

c# - 错误:ZLibStreamHandle 类型的 SafeHandle 或 CriticalHandle 未能正确释放

我对流的工作不多,所以我认为我这里的某个地方存在编码错误。

这是 SQL Server 2012 CLR 中的错​​误:

0 投票
1 回答
2075 浏览

c# - ObjectDisposedException - DangerousAddRef

我有一个有点复杂的 .net 控制台应用程序,它使用 WPF 来处理一些通知窗口,并执行一些 http 调用。在极少数情况下,该应用程序崩溃并且我能够获得的唯一错误消息来自 Windows 事件查看器:

我不知道堆栈跟踪来自哪里。任何想法在哪里寻找这个问题?以下是我的一些想法:

  • 既然堆栈上有这个计时器的东西,它可能与System.Threading.Timer有关吗?因为代码中使用了一些计时器?

  • 还涉及一些使用超时的 http 通信(httpclient、httpwebrequest)。可能与此错误有关吗?

抱歉这个非常不具体的问题,但我完全被困在这里,只需要某种起点。

0 投票
1 回答
166 浏览

c# - 具有内存压力的 SafeHandle

该类SafeHandle允许通过引用计数和 P/Invoke 编组器的合作安全访问 .NET 下的本机资源,以避免过早处理可能导致应用程序崩溃的句柄。

在某些情况下,通知垃圾收集器某些本机资源正在使用大量内存是有利的,例如,当所讨论的“句柄”是一个封装的本机库拥有的大缓冲区时。GC.AddMemoryPressure可用于此目的;但是,GC.RemoveMemoryPressure必须在“句柄”的生命周期结束时调用。

这两种方法似乎是不兼容的:SafeHandleis aCriticalFinalizerObject和它的ReleaseHandle方法在受约束的执行区域 (CER) 中运行。与GC.RemoveMemoryPressurenoReliabilityContractAttribute一样,不能从 CER 调用它(我猜在关键的完成时间,与内存压力有关的 GC 的某些部分可能不可用)。

我想到了两种方法,都非常不雅:

  1. 可以将 SafeHandle 包装到另一个对象中,该对象具有添加和删除内存压力的非关键终结器(和 Dispose 方法)。这有两个不足:首先,有人可以在不处理包装器的情况下处理 SafeHandle(它必须暴露才能传递给本地方法),因此内存压力被高估了。其次,当 SafeHandle 还活着时,包装器可能会变得未被引用,因此内存压力被低估了(可能更严重)。

  2. SafeHandle 有一个管理内存压力的非关键可终结类型的字段。在这种情况下,上面的大多数问题都消失了,但是,句柄无法在其 Dispose 或 ReleaseHandle 方法中释放内存压力对象,因为这会导致 CER 中的 GC.RemoveMemoryPressure 调用。可以提供另一种方法(例如 DisposeNoncriticial),但是当句柄被强制转换为 IDisposable 或在 using 块中使用时,这会导致“切片”问题。

是否有创建具有相关内存压力的 SafeHandle 的通用模式?