我在wpf应用程序中显示一个窗口时遇到问题,但是没有更新视图。将光标放在打开的窗口上时,会显示加载图标,窗口无响应。我认为这可能是由于某些线程问题我没有足够的经验看到。
以下是设置:
我的主程序在启动时运行,并创建和实现MainWindow窗口的实例,该窗口实现了自定义接口(IPlayer)。然后主程序运行一个与IPlayer交互以完成某项任务的过程,主要是主程序从MainWindow请求操作,这会提示用户输入某些输入并显示结果。
为了清晰起见,我会简化代码。假设这个程序只是运行一种聊天机器人游戏。
class MainProgram
{
[STAThread]
static void main(string[] args)
{
MainWindow wdw = new MainWindw();
Game g = new Game(wdw);
wdw.Show();
g.RunGame();
}
}
class Game
{
public IPlayer p;
Game(IPlayer) { this.p = p; }
public RunGame()
{
string r = GetResponse("How was your day?");
...
}
}
public partial class Human_Player : Window, IPlayer
{
public string GetResponse(string Question)
{
ShowQuestion(Question);
string r = GetResponse();
DisplayResponse(r);
return r;
}
...
}
我在一个单独的线程中运行RunGame(),如下所示:
Thread thread = new Thread(new ThreadStart(game.RunGame));
thread.Start();
但在响应中得到一个InvalidOperationException,指出“调用线程无法访问此对象,因为另一个线程拥有它。”
这里的任何帮助都会受到赞赏,因为我对这些东西很陌生。提前谢谢!
修改
只是为了澄清,我现在没有创建任何新线程。因此我认为我正在进行任何多线程。我打算在打开窗口后在主线程上运行game.RunGame()。 runGame方法由一个大循环组成,该循环调用Human_Player窗口上的一个更改UI的方法。
据我所知,只有两个主题: - 主线程 - MainProgram和Game在这里运行。我认为窗户也在这里运行,但我可能错了......请澄清一下 - 渲染线程 - 此处呈现UI。
答案 0 :(得分:1)
Argh,这个问题很多次被问到......你不能从与控件关联的Dispatcher线程不同的线程更新GUI控件。您需要使用Dispatcher.BeginInvoke运行更新代码,以从正确的线程更新GUI。
如果您没有从其他线程运行代码,那么您的方法执行时间可能太长,从而导致GUI挂起,因为事件线程被阻止接受用户输入。
答案 1 :(得分:0)
听起来您的游戏代码在循环中运行并且窃取了所有UI的处理时间。听起来你并没有向你的调度员发布控制权。
您的游戏代码不应该循环,它应该运行一次迭代,然后将控制权返回给调度程序。您需要创建一个定时器控件,它将定期调用您的游戏代码。