0

参考我目前正在构建的这个编程游戏。

我有一个类库(dll),它将有一个方法,该方法Run由以下内容组成:

public class MyRobot : Robot 
{
    public void Run(} 
    {
        while (true) 
        {
           Ahead(200); //moves the bot 200pixels
           TurnLeft(90); //turns the bot by 90deg 
        }
    }
}

在这些方法中(继承自Robot),系统将使用 WPF(使用BeginAnimationDispatcherTimer)为机器人设置动画。

现在,问题是在完成当前方法之前我没有返回方法(即继续下一个方法),因为这将导致动画一起发生,并且在无限循环中时(如上面一个),这尤其不好。


我的问题是,在完成动画之前防止方法返回的最佳方法是什么

我目前boolRobot类 ( isActionRunning) 中有一个标记为何true时开始运行动作,然后false在动画回调中更改为(Completed如果使用则使用事件BeginAnimation)。

在每个方法结束时(调用后BeginAnimation),我放置了以下循环:

while (isActionRunning) 
{
    Thread.Sleep(200); //so that the thread sleeps for 200ms and then checks again if the animation is still running 
}

这样该方法就不会在动画结束之前返回。

但我觉得这不是正确的做法。

谁能指导我实现这一目标的最佳方法?

4

3 回答 3

5

用锁建造信号装置是疯狂的。只需使用框架中已经存在的信号设备。

http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx

那就是:线程一说“嘿,线程二,开始这个动画,当你完成后,在这个等待句柄上给我发信号。” 然后线程一在等待句柄上等待。线程 2 启动动画,并在其完成事件中向等待句柄发出信号。线程一然后再次醒来并说“嘿线程二,开始另一个动画......”

于 2010-04-01T14:48:52.093 回答
3

这是一个选项,它仅在 Robot.Run 代码运行在与执行动画的 UI 线程不同的线程中时才有效。

在 Robot.Ahead 方法中(例如),使用 Dispatcher.Invoke(而不是 BeginInvoke)来调用启动动画的方法,而不是在机器人上添加一个带有空块的锁( lock(this) { } )。

在启动动画的方法中调用 Monitor.Enter(robot) 在启动动画之前

在动画完成处理程序调用 Monitor.Leave(robot)

结果将是

time      robot thread          UI thread  
  |       ---------------       --------------  
  |       call Invoke    --->  
  |                             lock robot (Monitor.Enter)  
  |                             begin animation  
  |       Invoke returns <---   return  
  |       lock(this)            (animation running)  
  |       (wait for lock  
  |       to become available)  
  |  
  |                             Animation complete  
  |                             release lock (Monitor.Exit)  
  |       (lock available,  
  |       continue running)  
  |       Release lock (exit lock block)  
  |       Return and start next  
  |       movement  
  \/  
于 2009-03-11T09:18:17.340 回答
0

我会做类似于你描述的事情。我最近在做一些事情,我调用了一堆异步操作,我想在调用另一个操作之前等待它们全部完成。我创建了一个集合来表示当前正在执行的所有操作,而不是直接将项目添加到集合中,我创建了用于添加和删除的方法。remove 方法的逻辑是“锁定集合,删除提供的密钥,如果为空则调用下一个操作”。您可以创建一个类似的机制,其中以应用程序或窗口为范围的集合跟踪正在执行的操作。您向集合添加一个密钥并将此密钥传递给您的异步操作。异步操作完成后,锁定集合并移除密钥。

这可能是矫枉过正,但我​​自己在这个问题上的经验有限。据我所知,.Net 甚至可能有一个针对这个问题的固定解决方案,它可以使用一两行代码。

于 2009-03-10T23:01:26.590 回答