c# - "Emulating"Application.Run 使用 Application.DoEvents

标签 c# forms opengl message-pump

我遇到麻烦了。我正在尝试使用 Application.DoEvents 模拟调用 Application.Run...这听起来很糟糕,然后我也接受我的问题的替代解决方案...

我必须像 Application.Run 那样处理消息泵,但我需要在消息处理前后执行代码。这是主要的重要代码片段。

// Create barrier (multiple kernels synchronization)
sKernelBarrier = new KernelBarrier(sKernels.Count);

foreach (RenderKernel k in sKernels) {
    // Create rendering contexts (one for each kernel)
    k.CreateRenderContext();
    // Start render kernel kernels
    k.mThread = new Thread(RenderKernelMain);
    k.mThread.Start(k);
}

while (sKernelBarrier.KernelCount > 0) {
    // Wait untill all kernel loops has finished
    sKernelBarrier.WaitKernelBarrier();
    // Do application events
    Application.DoEvents();
    // Execute shared context services
    foreach (RenderKernelContextService s in sContextServices)
        s.Execute(sSharedContext);

    // Next kernel render loop
    sKernelBarrier.ReleaseKernelBarrier();
}

这段代码由主例程执行。实际上,我有一个内核类列表,它们在单独的线程中运行,这些线程处理用于在 OpenGL 中呈现的表单。我需要使用屏障来同步所有内核线程,这非常有效。 当然,我需要在主线程(Main routine)中为创建的每个 Form 处理 Form 消息,实际上我调用 Application.DoEvents() 来完成这项工作。

现在我必须修改上面的代码片段以获得一个通用表单(简单对话框),而不会像 Application.Run 那样消耗 100% 的 CPU 调用 Application.DoEvents()。

目标应该是让上面的代码片段在到达时处理消息,并仅在必要时发出渲染(释放屏障),而不是试图获得最大 FPS;应该有可能切换到严格循环以尽可能多地渲染。

这怎么可能?

注意:上面的代码片段必须在主例程中执行,因为 OpenGL 上下文是在主线程上创建的。在单独的线程中移动代码片段并调用 Application.Run 非常不稳定且存在错误...

最佳答案

在循环中调用 Application.DoEvents() 没有任何根本性的错误。这就是 Form.ShowDialog() 所做的。它采取对策来确保用户不会遇到麻烦:它会禁用除对话框之外的所有窗口,因此用户无法退出应用程序或再次启动对话框。

您需要创建自己的,设置一个全局标志,指示您的主窗口已关闭,这样本地毯从您身下拉出时,您可以立即退出循环而无需调用任何更多代码。

您需要放弃处理器以避免 100% 的 CPU 负载。最简单的方法是调用 Thread.Sleep(1)。在 this thread 中查看我的答案举个例子。

关于c# - "Emulating"Application.Run 使用 Application.DoEvents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2547277/

相关文章:

c# - 如何更新由另一个组合框触发的组合框中的值?

php - Symfony2 实体字段类型当前选择

javascript - 在输入元素中隐藏文本

c++ - 尝试实现渲染到纹理

opengl - 将 DirectX 顶点转换为 OpenGL 顶点

opengl - 使用 OpenGL 时是否可以在 GPU 上执行浮点运算?

c# - 当你的实现是一个空方法时,你如何 "properly"实现 Dispose() (根据 FxCop)? (CA1063)

c# - 这个 API 到底是什么,它在做什么?

c# - 确定新日期是否为默认的 new DateTime()

javascript - 如何在没有输入的情况下通过自定义控件以 Angular 形式触发 change()