线程问题 - 窗口没有更新/响应

时间:2012-01-16 22:04:42

标签: c# wpf multithreading user-interface

  

可能重复:
  WPF and cross thread operations

我在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。

2 个答案:

答案 0 :(得分:1)

Argh,这个问题很多次被问到......你不能从与控件关联的Dispatcher线程不同的线程更新GUI控件。您需要使用Dispatcher.BeginInvoke运行更新代码,以从正确的线程更新GUI。

如果您没有从其他线程运行代码,那么您的方法执行时间可能太长,从而导致GUI挂起,因为事件线程被阻止接受用户输入。

答案 1 :(得分:0)

听起来您的游戏代码在循环中运行并且窃取了所有UI的处理时间。听起来你并没有向你的调度员发布控制权。

您的游戏代码不应该循环,它应该运行一次迭代,然后将控制权返回给调度程序。您需要创建一个定时器控件,它将定期调用您的游戏代码。

相关问题