我试图解决的症状是,我的XNA应用程序在最小化后的某些时间内不会恢复。我单击最小化按钮,但当我单击任务栏中应用程序的条目时,应用程序不会继续,而是保持最小化。此外,我听到一个Windows"丁"的声音效果播放。
如果我反复点击应用程序,它有时会恢复。我发现,如果我的应用程序在每帧Update调用中的处理时间较少,那么问题就更难重现。如果我加上这个:
System.Threading.Thread.Sleep(100);
那么几乎不可能恢复申请。
我发现,如果我在Program.Main上删除[STAThread],它总是完美地恢复;然而,我使用winforms-OpenFileDialog,它要求在Main方法上设置STAThread,所以我无法摆脱该属性。
有没有想过为什么会发生这种情况,以及是否有办法既使用STAThread又让应用程序正常恢复?
编辑:在内部,我的应用程序正在使用ThreadPool.QueueUserWorkItem,而这正是导致这种情况的原因。这是否意味着不应在STAThread应用程序中使用ThreadPool.QueueUserWorkItem?
您的意思是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#。