我从不对计时器和延迟工作太多,所以我很确定我的代码真的很难看,但我无法找到解决方案。
好的......我有一个名为AnimatorsPool的类,它一次包含并处理很多Animator类。动画师只是一个简单的,基于计时器的控制推动者。
public sealed class AnimatorsPool : IDisposable
{
private Boolean m_Disposed;
private Boolean m_Stopped;
private Boolean m_Waiting;
private Int32 m_DelayBetween;
private Int32 m_DelayStart;
private List<Animator> m_Animators;
private Stopwatch m_Stopwatch;
public Boolean AnimationsFinished
{
get
{
foreach (Animator animator in m_Animators)
{
if (!animator.AnimationFinished)
return false;
}
return true;
}
}
public AnimatorsPool(Int32 delayBetween, Int32 delayStart)
{
m_Disposed = false;
m_Stopped = false;
m_Waiting = false;
m_DelayBetween = ((delayBetween < 0) ? 0 : delayBetween);
m_DelayStart = ((delayStart < 0) ? 0 : delayStart);
m_Animators = new List<Animator>();
}
private void Wait(Int32 delay)
{
m_Stopwatch = Stopwatch.StartNew();
m_Waiting = true;
while (!m_Stopped && (m_Stopwatch.ElapsedMilliseconds <= delay))
Application.DoEvents();
m_Waiting = false;
m_Stopwatch.Stop();
}
public void Add(Animator animator)
{
m_Animators.Add(animator);
}
public void Dispose()
{
if (!m_Disposed)
{
foreach (Animator animator in m_Animators)
animator.Dispose();
m_Animators.Clear();
m_Animators = null;
m_Disposed = true;
}
GC.SuppressFinalize(this);
}
public void Start()
{
if (m_Animators.Count > 0)
{
if (m_DelayStart > 0)
Wait(m_DelayStart);
m_Animators[0].Start();
if (m_Animators.Count > 1)
{
for (Int32 i = 1, length = m_Animators.Count; i < length; ++i)
{
if (m_DelayBetween > 0)
Wait(m_DelayBetween);
m_Animators[i].Start();
}
}
}
}
public void Stop()
{
m_Stopped = true;
while (m_Waiting)
Application.DoEvents();
}
}
在我的主窗体中,有时使用AnimatorsPool,我使用以下代码:
using (AnimatorsPool pool = new AnimatorsPool(100, (delayAction ? 100 : 0)))
{
m_AnimatorsPools.Add(pool);
for (Int32 i = (controlsCount - 1); i >= 0; --i)
{
Animator animator = new Animator(controls[i], coordinates[i], 50);
pool.Add(animator);
}
pool.Start();
while (!pool.AnimationsFinished)
Application.DoEvents();
m_AnimatorsPools.Remove(pool);
}
现在好了......开头发生的事情是,如果我在AnimatorsPool仍在运行Wait()方法时退出程序,我的主窗体正在消失,但由于这个过程,我的任务管理器中的进程仍然无法运行。 所以我在我的主窗体中实现了Dispose覆盖:
protected override void Dispose(Boolean disposing)
{
if (!m_Disposed)
{
if (disposing)
{
s_RandomProvider.Dispose();
foreach (AnimatorsPool pool in m_AnimatorsPools)
pool.Dispose();
m_AnimatorsPools.Clear();
m_AnimatorsPools = null;
}
m_Disposed = true;
}
base.Dispose(disposing);
}
好的...现在我的程序有时会正常退出,但有时候不会。而我从调试中看到的是,当它发生时,这是因为即使m_Stopped设置为true,一些AnimatorsPool仍在运行Wait()方法。 我想我应该使用线程,计时器或类似的东西,但我没有经验。欢迎任何帮助!谢谢!
答案 0 :(得分:0)
无论你做什么,都不要这样做:
while (!m_Stopped && (m_Stopwatch.ElapsedMilliseconds <= delay))
Application.DoEvents();
您应该使用计时器和事件驱动,而不是忙碌等待。这在嵌入式实时内容中一直没问题。
你需要重写你的代码,如果没有在定时器和事件驱动的开发中创建课程,很难给出指针。
编辑:来自MSDN中的Application.DoEvents
文档(强调我的):
调用此方法会导致当前线程在所有等待时暂停 窗口消息被处理。如果消息导致事件被触发,那么 应用程序代码的其他区域可能会执行。 这可能会导致您的申请 展示难以调试的意外行为。如果您执行 花费很长时间的操作或计算,通常是优选的 在新线程上执行这些操作。有关异步的更多信息 编程,请参阅Asynchronous Programming Overview。