我喜欢使用 G1ANT 的“宏”功能来调用非托管代码,但非托管对象当然不会被自动垃圾收集,没有代码来执行此操作。
我的请求专门针对在这些 G1ANT C# 宏中处理非托管代码的最佳实践,而不是在 C# 中处理相同的代码,也不是修复以下代码的请求,它运行得很好。
如果我使用 Visual Studio 在 C# 中进行编码,我可能会使用 System.Runtime.InteropServices.SafeHandle 类,覆盖 Finalize 方法,或使用其他常用方法之一(另请参阅这篇关于在C#)。
但是这些方法似乎都不适合 G1ANT 宏本身,至少以我的新手经验来看。
出于说明目的,我指的是这个 G1ANT 代码,但没有宏 ( ) 中的最后一行ahk.Reset()
,因为它在该行中运行良好,不止一次。(我痛苦地意识到必须有一个更好的例子,但由于我是 G1ANT 的新手,这是我目前唯一拥有的东西。)我所追求的是在 G1ANT 中工作的 C#代码未明确处置非托管对象:
addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");
//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");
string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);
//execute's newly made function\
ahk.ExecRaw(@"SayHello(""Mario"") ");
var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll,System.Reflection.dll,Microsoft.CSharp.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms,System.Reflection
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");
//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");
string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);
//executes new function
ahk.ExecRaw(@"SayHello(""Mario"") ");
var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
ahk.Reset();
⊃
⊃
它几乎是从AutoHotkey.Interop github 页面逐字记录的。
没有宏中的最后一行('ahk.Reset()),代码第一次运行完美,但在第二次运行时,G1ANT 仍然看到包含的 AutoHotkey 文件,并警告重复的函数定义,但继续运行并且仍然有效适当地。as-far-as-I-can-tell-undocumented AutoHotkey.Interop 命令Reset()
通过调用处理垃圾收集问题
public void Terminate()
{
AutoHotkeyDll.ahkTerminate(1000);
}
public void Reset() {
Terminate();
AutoHotkeyDll.ahkReload();
AutoHotkeyDll.ahktextdll("", "", "");
}
因此,即使没有 , AutoHotkeyEngine 实例本身似乎也已被垃圾回收ahk.Reset();
,但它加载到对象中的 AutoHotkey 脚本却不是。
停止 G1ANT.Robot 应用程序并重新启动,然后重新加载上面的脚本(如前所述,没有行ahk.Reset();
),工作正常,但再次仅用于单次运行。
编辑:给定答案关于单例处理的建议是我以后在加载 AutoHotkey 函数脚本和 DLL 本身时将使用的。检查 DLL 或函数文件是否已加载,是否存在问题,这似乎是一种谨慎且良好的做法。“一盎司的预防”等。此外,我在这里分叉了 AutoHotkey.Interop 存储库,添加了一个布尔检查以查看 AutoHotkeyEngine 实例是否已准备好。
此致,
burque505