C#问题记录-CallbackOnCollectedDelegate
做项目的时候遇到了这个问题:
检测到:CallbackOnCollectedDelegate
对“xx.HookProc::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
callbackOnCollectedDelegate MDA
.NET Framework 4如果将一个委托作为函数指针从托管代码封送到非托管代码,并且在对该委托进行垃圾回收后对该函数指针发出了一个回调,则将激活 callbackOnCollectedDelegate 托管调试助手 (MDA)。
尝试通过从托管委托获取的函数指针调入托管代码时发生访问冲突。 这些故障虽然不是公共语言运行时 (CLR) bug,但是会显示为公共语言运行时 bug,因为 CLR 代码中发生了访问冲突。
此故障的具体情况并非千篇一律:有时对函数指针发出的调用可以成功,有时却会失败。 仅在负载过大或按随机次数进行尝试时会发生此故障。
从其创建函数指针并将创建的函数指针公开给非托管代码的委托已被垃圾回收。 当非托管组件尝试对该函数指针发出调用时,会产生访问冲突。
该故障是随机出现的,因为它的出现取决于垃圾回收发生的时间。 如果某个委托符合回收条件,则会在回调之后进行垃圾回收,并且调用会成功。 在其他一些情况下,垃圾回收发生在回调之前,回调会引发访问冲突,并且程序会停止。
该故障发生的可能性取决于从封送委托到对函数指针发出回调之间的时间以及垃圾回收的频率。 如果从封送委托到接着发生的回调之间的时间很短,则发生该故障会的机会就很少。 通常情况下,如果接收函数指针的非托管方法没有保存该函数指针以备以后使用,而是立即对函数指针发出回调以便在返回之前完成其操作,就很少发生这种故障。 同样道理,系统负载过大时会发生更多垃圾回收,进而使得垃圾回收更有可能在回调之前发生。
一旦将委托作为非托管函数指针封送出去,垃圾回收器就无法跟踪其生存期。 这样,在该非托管函数指针的生存内,您的代码必须保持一个指向该委托的引用。 但是在此之前,您首先必须确定回收了哪个委托。 激活 MDA 之后,MDA 会提供该委托的类型名称。 请使用此名称在您的代码中搜索将该委托外传给非托管代码的平台调用或 COM 签名。 通过这些调用站点之一将有问题的委托传递出去。 您还可以启用 gcUnmanagedToManaged MDA 以强制在每次向运行时发出回调之前都进行垃圾回收。 这样可以确保在回调之前总是进行垃圾回,从而可以消除由垃圾回收引起的不确定性。 一旦您得知回收了哪个委托,请更改您的代码,以便在封送的非托管函数指针的生存期内在托管端保持对该委托的引用。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace testNotifyIcon
{
#region 委托
internal delegate int HookProc(int code, int wParam, IntPtr lParam);//声明委托
#endregion
//略去若干行代码
/// <summary>
/// Win32函数库(仅摘录用到的函数)
/// </summary>
internal static class Win32Lib
{
#region 字段
public static HookProc hookproc;//这里是重点
public const string ATOM_FLAG = "HookSysKey";
public const string SHELL_FALG = "Winlogon";
; //注入代码所占的双字数
); //字节数
; //注入代码线程函数偏移量
public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
public const UInt32 TOKEN_QUERY = 0x0008;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
public const string SE_DEBUG_NAME = "SeDebugPrivilege";
;
#endregion
#region 外部函数
#region user32.dll
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SetWindowsHookEx(int hookType, HookProc lpfn, IntPtr pInstance, int threadId);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(IntPtr pHookHandle, int nCode, int wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool BlockInput(bool fBlockIt);
#endregion
//此处略图N行代码
#endregion
}
}
InputHook.cs
//略去N行代码 IntPtr pInstance = Win32Lib.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); Win32Lib.hookproc = new HookProc(LowLevelKeyboardProc);//此为重点 //安装钩子 m_lHookID = Win32Lib.SetWindowsHookEx( (int)HookType.WH_KEYBOARD_LL, Win32Lib.hookproc,//此为重点 pInstance, ); //略去N行代码
重点就是这样
internal delegate int HookProc(int code, int wParam, IntPtr lParam);
public class test
{
private static HookProc hookproc;
hookproc = new HookProc(xxx);
SetWindowsHookEx(,hookproc , Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[]), );
}
C#问题记录-CallbackOnCollectedDelegate的更多相关文章
- 记一次debug记录:Uncaught SyntaxError: Unexpected token ILLEGAL
在使用FIS3搭建项目的时候,遇到了一些问题,这里记录下. 这里是发布搭建代码: // 代码发布时 fis.media('qa') .match('*.{js,css,png}', { useHash ...
- nginx配置反向代理或跳转出现400问题处理记录
午休完上班后,同事说测试站点访问接口出现400 Bad Request Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...
- Kali对wifi的破解记录
好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...
- 2015 西雅图微软总部MVP峰会记录
2015 西雅图微软总部MVP峰会记录 今年决定参加微软MVP全球峰会,在出发之前本人就已经写这篇博客,希望将本次会议原汁原味奉献给大家 因为这次是本人第一次写会议记录,写得不好的地方希望各位园友见谅 ...
- 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)
分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...
- 我是如何在SQLServer中处理每天四亿三千万记录的
首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...
- 前端学HTTP之日志记录
前面的话 几乎所有的服务器和代理都会记录下它们所处理的HTTP事务摘要.这么做出于一系列的原因:跟踪使用情况.安全性.计费.错误检测等等.本文将谥介绍日志记录 记录内容 大多数情况下,日志的记录出于两 ...
- ASP.NET Core应用中如何记录和查看日志
日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性.我们知道ASP.NET Core使用的是一个极具扩展性的日志系统,该系统由Logger.Logger ...
- python+uwsgi导致redis无法长链接引起性能下降问题记录
今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...
随机推荐
- ARC097E Sorted and Sorted
传送门 题目 There are 2N balls, N white and N black, arranged in a row. The integers from 1 through N are ...
- C#监听窗体新建/鼠标移入移出
在新建window窗体时会激活方法,并循环所有窗体,鼠标移动在重写方法的页面中也会激活 winform直接在继承了From窗体cs中 protected override void WndProc(r ...
- Ubuntu使用技巧
命令 获取系统安装包的编译源码及脚本 apt-get source package 查询端口被占用的进程 lsof -i:端口号 配置 配置阿里源 # mv /etc/apt/source.list ...
- mysql 索引总结
一.MYSQL索引类型(共三种) 1).normal 正常 应用场景:普通的index 2).unique 唯一性的 应用场景:比如身份证的 3).full text 全文索引 应用场景:较长文字 二 ...
- PAT1060【大模拟啊】
怎么麻烦怎么来了??? 提供几个案例: 5 0.00001 0.00001 0 0.0 0.0222 1 0.001 0.2000 2 005.06 0.230 1 00.020 0 贴份代码跑.. ...
- java加密MD5实现及密码验证
package test; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; impor ...
- java学习笔记——基于Robot类的屏幕分享
直接上代码,具体看注释: package robot; import java.awt.AWTException; import java.awt.Dimension; import java.awt ...
- 《OD大数据实战》Spark入门实例
一.环境搭建 1. 编译spark 1.3.0 1)安装apache-maven-3.0.5 2)下载并解压 spark-1.3.0.tgz 3)修改make-distribution.sh VER ...
- 课堂笔记 layout 布局、手风琴accordion、选项卡tabs
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 洛谷 P1551 亲戚(并查集模板)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P1551 思路: 很显然地我们会发现,这是一道并查集的模板题,并且是考察了并查集中的”并“和”查“的操 ...