我试图连续运行代码,尽可能快地执行一个函数(除非有一个指定的速率)。当我以前使用d java时,有一个调度器,或者计时器,我用它在一定的延迟内连续运行代码,没有多线程。我正在寻找类似的东西,但没有延迟。
我已经尝试过多线程,然后使用while循环,用thread.sleep添加可选的延迟,然后调用一个方法返回主线程。这样做的问题是,它冻结了我的进程,并导致它在任务管理器中“不响应”。虽然它不中断主线程,这意味着它按预期运行,呈现一切,但它使任务“不响应”。这不允许我与最大化、关闭按钮、调整大小等进行交互。这是我的多线程代码。
public void Init()
{
Thread thread = new Thread(Loop);
thread.Start();
}
public void Loop()
{
while (true)
{
if (InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(delegate { RenderFrame(); }));
}
if (maxFps > 0)
{
Thread.Sleep(1000 / maxFps);
}
}
}
如果有人知道我如何在不冻结进程的情况下获得相同的结果,或者在不使用多线程的情况下获得相同的结果,请给予我一些建议!!
编辑:我决定只使用计时器,它会稍微慢一点,不过没关系,我想。最后一个问题是,有时当关闭或点击winform时,我的循环结束,它停止调用render函数。我使用的是:
var timer = new System.Threading.Timer((e) =>
{
this.BeginInvoke(new MethodInvoker(delegate { RenderFrame(); }));
}, null, 0, 1);
1条答案
按热度按时间o4tp2gmn1#
您正在启动一个线程,该线程除了用数百万条消息轰炸UI消息循环之外什么也不做。这不是线程的好用法。当您有与UI无关的工作要做时,您需要一个后台线程,并且在您的情况下,似乎所有的工作都与操作UI组件相关。因此,所有的工作都应该发生在UI线程上。为了在无限循环运行时保持UI的响应性,可以将
Loop
转换为async
方法(async Task
或async void
),并将Thread.Sleep()
替换为await Task.Delay()
:除了
while (true)
,您可以检查主窗体仍然打开的条件,否则循环将在关闭窗体后继续,最有可能导致ObjectDisposedException
。