等待另一个线程中的计时器滴答声



我使用一个简单的Lua解释器,允许用户使用C#程序在现实世界中移动机械臂。

Lua中的move函数应该是阻塞的(并且只有在移动完成后才返回(,这样程序就尽可能简单地为用户编写和理解。我正在尝试用C#编写这个阻塞函数。

为了简单起见,假设我可以用计时器读取文件中机器人的状态。本质上,函数应该";等待";计时器勾选,然后选择返回或继续等待。我知道这听起来很奇怪,但希望你能理解我需要什么。以下是我的代码的简化版本:

using Neo.IronLua;
namespace WinFormsApp5 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
// Timer
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 500;
timer.Elapsed += Timer_Elapsed;
timer.Start();
// Interpreter
using (Lua l = new Lua()) {
var g = l.CreateEnvironment();
dynamic dg = g;
dg.move = new Action<int, int, int>(move);                   // ↓ calling the function from Lua
Task.Factory.StartNew(() => g.DoChunk("print('Hello World!'); move(5, 5, 10)", "test.lua")); // using a task not to block the UI thread
}
}
private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) {
System.Diagnostics.Debug.WriteLine("timer tick");
try {
if (System.IO.File.ReadAllText("state.txt") != "moving") {
// tell the move function to return
}
} catch { }
}
public static void move(int x, int y, int z) {
System.Diagnostics.Debug.WriteLine($"start {x} {y} {z}");
Thread.Sleep(2000); // wait here for the movement to finish
System.Diagnostics.Debug.WriteLine("done");
}
}
}

有没有一种方法可以使用任务、异步、等待之类的东西来实现这种行为?我是异步编程和线程的新手。如有任何帮助,我们将不胜感激。

使用ManualResetEventSlim怎么样?

您的代码可能看起来像:

private readonly ManualResetEventSlim _movementFinished = new();
private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) {
System.Diagnostics.Debug.WriteLine("timer tick");
try {
if (System.IO.File.ReadAllText("state.txt") != "moving" &&
!this._movementFinished.IsSet) {
this._movementFinished.Set();
}
} catch { }
}
public static void move(int x, int y, int z) {
this._movementFinished.Reset();

System.Diagnostics.Debug.WriteLine($"start {x} {y} {z}");
// Thread.Sleep(2000); // wait here for the movement to finish
this._movementFinished.Wait();
System.Diagnostics.Debug.WriteLine("done");
}

这看起来很奇怪,也许您需要一个逻辑来确保movingstate.txt-文件中,以防止出现意外行为。

顺便说一句:你的Ctor看起来很奇怪,因为你创建了一个一次性的Lua实例,运行了一个任务,但你的Lua实例可能在任务完成之前就被释放了。

最新更新