终止 NLua 脚本执行
2020-6-19 12:41:33
收藏:0
阅读:174
评论:1
我正在使用 NLua 在我的应用程序中运行 Lua 脚本。我需要实现在任何时候终止在单独线程中运行的脚本的能力,例如用户按下“停止”按钮,脚本必须立即终止。我已经阅读了有关 SetDebugHook 的资料,并尝试了关闭 Lua State 并在状态上调用 Error,但我总是会得到 AccessViolationException。
我尝试过
Lua env = new Lua(); // 在主线程中创建
env.DoString(); // 在第二个线程中调用
// 在主线程中调用
public void Stop()
{
env.Close(); // 不起作用。AccessViolationException
env.State.Close(); // 不起作用。AccessViolationException
env.State.Error("err"); // 不起作用。AccessViolationException
}
尝试使用锁同步线程
lock (locker)
{
if (env.IsExecuting)
env.Close();
}
相同问题。AccessViolationException
谢谢。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

这种方法,利用
lua_sethook在执行每行 lua 代码之前检查信号以实现中止,效果还不错:public partial class NluaThreading : Form { private Lua state; private bool abort; public NluaThreading() { InitializeComponent(); } private void Start_Click(object sender, EventArgs e) { state = new Lua(); state.SetDebugHook(KeraLua.LuaHookMask.Line, 0); state.DebugHook += State_DebugHook; abort = true; //强制在第一个 debughook 事件后中止 new Thread(DoLua).Start(); } private void State_DebugHook(object sender, NLua.Event.DebugHookEventArgs e) { if (abort) { Lua l = (Lua)sender; l.State.Error("Execution manually aborted"); } } private void DoLua() { try { state.DoString("while(true) do end"); } catch (Exception e) { MessageBox.Show(e.Message, "DoLua", MessageBoxButtons.OK); } } }当然,这会增加每行的开销,为了减少这种开销,可以将钩子改为其他值之一。
另一种选择是使用 lua 线程监视并在需要时中止的标记,但这种方法需要在 lua 脚本内进行一些处理:
public partial class NluaThreading : Form { internal class Tokens { public bool abort = false; } private Lua state; private Tokens tokens; public NluaThreading() { InitializeComponent(); state = new Lua(); tokens = new Tokens(); state["tokens"] = tokens; //现在标记在 lua 内部可见,并将反映我们从主线程进行的更改 } private void Start_Click(object sender, EventArgs e) { if (!state.IsExecuting) { tokens.abort = false; new Thread(DoLua).Start(); } } private void Stop_Click(object sender, EventArgs e) => tokens.abort = true; private void DoLua() => state.DoString("repeat print(tokens.abort) until(tokens.abort); print(tokens.abort)"); }通常情况下,您的 lua 执行会更加复杂,包含许多嵌套的循环,在这些情况下,您可以在 lua 中实现一个函数来检查标记,并在标记为 true 时抛出错误:
function checkTokens() if tokens.abort then error('Execution manually aborted') end end然后对
DoLua函数进行一些更改:private void DoLua() { try { state.DoString("while(true) do print(tokens.abort); checkTokens(); end"); } catch(Exception e) { MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK); } }