- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在工作中,我们有一个本地 C 代码负责读取和写入专有平面文件数据库。我有一个用 C# 编写的包装器,它将 P/Invoke 调用封装到一个 OO 模型中。自项目启动以来,用于 P/Invoke 调用的托管包装器的复杂性已大大增加。有趣的是,当前的包装器运行良好,但我认为我实际上需要做更多工作以确保正确运行。
答案提出的一些注意事项:
这是修改后的代码示例:
[DllImport(@"somedll", EntryPoint="ADD", CharSet=CharSet.Ansi,
ThrowOnUnmappableChar=true, BestFitMapping=false,
SetLastError=false)]
[ReliabilityContract(Consistency.MayCorruptProcess, Cer.None)]
internal static extern void ADD(
[In] ref Int32 id,
[In] [MarshalAs(UnmanagedType.LPStr)] string key,
[In] byte[] data, // formerly IntPtr
[In] [MarshalAs(UnmanagedType.LPArray, SizeConst=10)] Int32[] details,
[In] [MarshalAs(UnmanagedType.LPArray, SizeConst=2)] Int32[] status);
public void Add(FileId file, string key, TypedBuffer buffer)
{
// ...Arguments get checked
int[] status = new int[2] { 0, 0 };
int[] details = new int[10];
// ...Make the details array
lock (OPERATION_LOCK)
{
ADD(file.Id, key, buffer.GetBytes(), details, status);
// the byte[], details, and status should be auto
// pinned/keepalive'd
if ((status[0] != 0) || (status[1] != 0))
throw new OurDatabaseException(file, key, status);
// we no longer KeepAlive the data because it should be auto
// pinned we DO however KeepAlive our 'file' object since
// we're passing it the Id property which will not preserve
// a reference to 'file' the exception getting thrown
// kinda preserves it, but being explicit won't hurt us
GC.KeepAlive(file);
}
}
我的(修改后的)问题是:
编辑:我最近发现了一张图表,它激发了我的好奇心。它基本上指出,一旦您调用 P/Invoke 方法,GC can preempt your native code .因此,虽然 native 调用可能是同步进行的,但 GC 可以选择运行并移动/删除我的内存。我想现在我想知道自动固定是否足够(或者它是否运行)。
最佳答案
除非您的非托管代码直接操作内存,否则我认为您不需要固定对象。 Pinning 本质上是通知 GC 在收集周期的压缩阶段它不应该在内存中移动该对象。这仅对非托管内存访问很重要,在这种情况下,非托管代码期望数据始终位于传入时的相同位置。GC 运行的“模式”(并发或抢占)应该对固定没有影响对象作为固定的行为规则适用于任一模式。 .NET 中的编码基础结构试图在如何编码托管/非托管代码之间的数据方面变得聪明。在这种特定情况下,您正在创建的两个数组将在编码过程中自动固定。
除非您的非托管 ADD 方法是异步的,否则可能也不需要调用 GC.KeepAlive。 GC.KeepAlive 仅用于防止 GC 在长时间运行操作期间回收它认为已死的对象。由于文件作为参数传入,它可能在调用托管 Add 函数后在代码的其他地方使用,因此不需要 GC.KeepAlive 调用。
您编辑了代码示例并删除了对 GCHandle.Alloc() 和 Free() 的调用,这是否意味着代码不再使用它们?如果您仍在使用它,您的 lock(OPERATION_LOCK) block 中的代码也应该包含在 try/finally block 中。在你的 finally block 中,你可能想做这样的事情:
if (dataHandle.IsAllocated)
{
dataHandle.Free();
}
另外,您可能想要验证调用 GCHandle.Alloc() 不应该在您的锁内。通过将它放在锁之外,您将有多个线程分配内存。
就自动固定而言,如果数据在编码过程中被自动固定,则它会被固定并且不会在 GC 收集周期中移动(如果在您的非托管代码运行时发生)。我不确定我是否完全理解您关于继续调用 GC.KeepAlive 的原因的代码注释。未经修改的代码是否真的为 file.Id 字段设置了值?
关于c# - P/Invoke、Pinning 和 KeepAlive 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/528517/
几个月来我们遇到了一个奇怪的小问题: 我们集群上的负载(http、具有大量非常短(<100ms)请求的持久保持事件连接)分布非常不均匀。所有服务器都以相同的方式配置,但某些每秒推送数千个请求的连接最终
几个月来我们遇到了一个奇怪的小问题: 我们集群上的负载(http,具有大量非常短(<100 毫秒)请求的长期保持事件连接)分布非常不均匀。所有服务器都以相同的方式配置,但一些每秒推送数千个请求的连接最
List resultList = lists.iterator().next(); for (Iterator iterator = lists.iterator(); iterator.h
根据 PostgresSQL docs有参数 keepalives 和进一步的参数 keepalives_idle, keepalives_interval 和 keepalives_count 只有
我最近接手了一个 Android 项目。我们希望尝试加快我们拥有的同步过程。这是目前的代码: System.setProperty("http.keepAlive", "false"); 我没有写代码
我应该使用什么代码片段来配置普通的 Jersey Client 实例以“保持 Activity ”连接?谢谢! 最佳答案 假设您指的是 HTTP keep-alives,默认情况下支持它,并且可以通过
在套接字上的 accept() 之后,我正在尝试配置 TCP keepalive。 SockConnected = accept(SockListen, &RemoteAddr,
在 nginx.org 中,keepalive config 的默认值是 —,但我不太明白这是什么意思。 Syntax: keepalive connections; Default: — Co
我已经升级到 0.9.0.1,看起来很顺利,我的 meteor 网站运行良好。 但是,在对模板进行简单更改时(字面上更改跨度内的文本),我在服务器控制台中收到错误,然后服务器重新启动。 服务器控制台日
在 SignalR (1.2.2) 中,KeepAlive 和 ConnectionTimeout 之间有什么区别? 通过保持事件状态主动 ping 服务器,连接永远不会超时。那么Connection
我的 grunt 任务如下所示: grunt.registerTask "default", [ "clean:dist" # "useminPrepare" "copy:di
我管理着几个 DNN 门户,我需要一个解决方案来让它们在流量空闲时保持“活跃”。在给定的不活动时间后,IIS 将从内存中卸载 DNN 应用程序,这将影响第一个客户端请求的加载时间。 DNN 有一个“K
我正在尝试使用服务器发送事件传输查看从 Signalr 服务器发送的保持事件事件。我正在使用 Fiddler 来查看它,并且启用了“Stream”Fiddler 功能按钮......到目前为止我没有看
使用apache,当KeepAlive为Off时减少MaxClients是否合理?目前,MaxClients 设置为 150,这是 mpm-worker 的默认值。 nginx 为 apache 提供
我有一个 mediaOutput 标签,它的 createContent 属性要求支持 bean 处于某种状态。必须提供填充在 init 方法中的值列表。 因此,我为整个支持 bean 添加了一个 k
我设置了客户端和服务器之间有防火墙的设置。我连接到两个不同的服务器,即 A 和 B,数据可以在任何时间点从 A 或 B 流动,但一次只能流动一个。似乎我与服务器的连接每 2 小时 11 分 15 秒后
在 Android WebView 中创建 XMLHttpRequests 时,没有像看起来那样使用保活连接。 当请求频繁发出时,我的桌面浏览器都使用 keepalive(例如,在页面的 onload
场景如下: 有一个 http 反向代理,它有一个与应用程序服务器的持久连接池。它已经收到来自客户端的请求,并在检查连接是否打开后向后端发出相同的请求 与此同时,服务器在收到请求之前关闭了连接,代理因从
在他的article about preventing multiple instances Michael Covington 展示了一个应用程序的代码: static void Main()
当我执行 netstat -anto 时,我得到了以下输出 Proto Recv-Q Send-Q Local Address Foreign Address
我是一名优秀的程序员,十分优秀!