为什么在XNA游戏中使用慢速FPS将[STAThread]放在Program.Main上会阻止最小化还原

本文关键字:Main Program 放在 还原 最小化 STAThread 游戏 XNA FPS 为什么 | 更新日期: 2023-09-27 18:28:05

我试图解决的症状是,我的XNA应用程序在最小化后的某些时间内不会恢复。我单击最小化按钮,但当我单击任务栏中应用程序的条目时,应用程序不会继续,而是保持最小化。此外,我听到一个Windows"丁"的声音效果播放。

如果我反复点击应用程序,它有时会恢复。我发现,如果我的应用程序在每帧Update调用中的处理时间较少,那么问题就更难重现。如果我加上这个:

 System.Threading.Thread.Sleep(100);

那么几乎不可能恢复申请。

我发现,如果我在Program.Main上删除[STAThread],它总是完美地恢复;然而,我使用winforms-OpenFileDialog,它要求在Main方法上设置STAThread,所以我无法摆脱该属性。

有没有想过为什么会发生这种情况,以及是否有办法既使用STAThread又让应用程序正常恢复?

编辑:在内部,我的应用程序正在使用ThreadPool.QueueUserWorkItem,而这正是导致这种情况的原因。这是否意味着不应在STAThread应用程序中使用ThreadPool.QueueUserWorkItem?

为什么在XNA游戏中使用慢速FPS将[STAThread]放在Program.Main上会阻止最小化还原

您的意思是STAThreadAttribute吗?如果没有,请将其放在主方法上。

我使用STAThreadAttribute和ThreadPool.QueueUserWorkItem,没有此问题。请注意,Sleep()是专门阻止窗口响应的,因为它阻塞了线程。理想情况下,你不应该在游戏的主线程上使用睡眠。

我使用了一种不同的方法来解决这个问题。为了防止对话框和表单阻塞主线程,我将代码放在一个单独的子例程中,并启动一个新线程:

Protected Overrides Sub Update(gametime As GameTime)
    ...
    If (Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.O)) Then ' load a new object
         If loadthreadrunning = False Then
             loadthreadrunning = True
             Dim thread As New Thread(AddressOf BackgroundLoader)
             thread.SetApartmentState(ApartmentState.STA)
             thread.Start()
         End If
    End If
    ...
End Sub
...
Sub BackgroundLoader()
    Dim fd As New OpenFileDialog
    Dim dlgres As DialogResult
    dlgres = fd.ShowDialog()
    ...
    loadthreadrunning = False
End Sub 

当然,我的代码是用VB编写的,但同样的技术也适用于C#。