C# 调用隐藏表单时出现按键异常

C# 调用隐藏表单时出现按键异常,c#,winforms,exception,C#,Winforms,Exception,可能重复: 我在调用我的主窗体和唯一窗体时遇到了一个异常,因为它不可见。我有一个钥匙钩,用来寻找能让它再次可见的钥匙。然而,问题是,当按下该键并加载表单时,我遇到了此异常 对类型为“MyProgram!”的垃圾回收委托进行了回调!globalKeyboardHook+keyboardHookProc::Invoke'。这可能会导致应用程序崩溃、损坏和数据丢失。当将委托传递给非托管代码时,托管应用程序必须使委托保持活动状态,直到保证永远不会调用委托为止 由于这是我第一次处理键钩子,或者在不使用另

可能重复:

我在调用我的主窗体和唯一窗体时遇到了一个异常,因为它不可见。我有一个钥匙钩,用来寻找能让它再次可见的钥匙。然而,问题是,当按下该键并加载表单时,我遇到了此异常

对类型为“MyProgram!”的垃圾回收委托进行了回调!globalKeyboardHook+keyboardHookProc::Invoke'。这可能会导致应用程序崩溃、损坏和数据丢失。当将委托传递给非托管代码时,托管应用程序必须使委托保持活动状态,直到保证永远不会调用委托为止

由于这是我第一次处理键钩子,或者在不使用另一个窗体的情况下返回窗体,所以我在这里有点不知所措。我不确定它想达到什么目的。我是否应该将窗体的不透明度设置为0,以防止程序试图关闭窗体

公共部分类Form1:Form {


请注意,没有更多的实用程序名称空间,因为我在用Form1代码合并后划伤了它。

我认为您在删除对它的引用后试图访问实用程序实例,例如:

Utilities utilities = new Utilities();
SomeMethodDelegate method = utilities.SomeMethod();
// ...
utilities = someOtherUtilitiesInstanceOrNull;
method(); // This is referencing a method that is now probably collected by the garbage collector.
当然,将Utilities类设置为静态可能是一个更好的主意,这取决于您的模型。

问题出在哪里 您的问题是,您正在向非托管代码传递一个委托,但没有在托管代码中保留对它的引用。由于您没有对它的引用,GC假定它可以安全地收集

我无法在你的代码中指出它,因为你还没有发布任何,但这里有一种可能性

您可以隐式创建委托:

SomeUnmanagedMethod(someCallback);
这可以转化为如下内容:

SomeUnmanagedMethod(new SomeDelegate(someCallback));
如您所见,委托的新实例从未被引用,因此超出范围并被收集

解决方案 您需要在托管代码中维护对委托的引用。一种方法是在实用程序类中创建静态变量:

然后,您可以存储对代理的引用,替换原始代码:

callback = someCallback;
SomeUnmanagedMethod(callback);
不幸的是,我无法给出更具体的答案,因为您还没有发布任何代码


另请参见。

是否在窗体上使用Close?或者是否更改指向MainForm实例的变量?我将窗体的visible属性更改为false。实用程序类是实例类吗?它包含globalKeyboardHook的类。无法创建静态类“MyProgram.Form1.globalKeyboardHook”的实例实用程序是命名空间中,我将globalKeyboardHook类合并到同一个区域中,但是在尝试使其成为静态时引发了此错误。您不应该尝试创建它的实例。您应该直接调用globalKeyboardHook.someMethod之类的方法,而不必执行globalKeyboardHook instance=new globalKeyboardHook。我将在eantime,如果您想查看,我会发布我的代码。我很抱歉没有这样做。您的问题在第hhook=setWindowshookxwh\u-KEYBOARD\LL,hookProc,hInstance,0;行。您应该将hookProc委托存储在globalKeyboardHook类的字段中,而不是动态创建它。我明白您的意思,谢谢。我如果我再次遇到类似的事情,我会记住这一点。我会投你一票,但显然我没有足够的众议员。呸。如果有帮助的话,你仍然可以将我的帖子标记为答案。
static SomeDelegate callback;
callback = someCallback;
SomeUnmanagedMethod(callback);