C# 线程问题-窗口未更新/响应

C# 线程问题-窗口未更新/响应,c#,wpf,multithreading,user-interface,C#,Wpf,Multithreading,User Interface,可能重复: 我的wpf应用程序中有一个窗口无法显示,但无法更新视图。将光标放在打开的窗口上时,将显示加载图标,窗口将无响应。我认为这可能是由于一些线程问题,我没有足够的经验,看到 以下是设置: 我的主程序在启动时运行,并创建实现自定义界面(IPlayer)的MainWindow窗口的实例。然后,主程序运行一个进程,该进程与IPlayer交互以完成某些任务,其思想是主程序从主窗口请求操作,从而提示用户输入某种类型的内容并显示结果 为了清晰起见,我将简化代码。假设这个程序只是运行一种聊天机器人游

可能重复:

我的wpf应用程序中有一个窗口无法显示,但无法更新视图。将光标放在打开的窗口上时,将显示加载图标,窗口将无响应。我认为这可能是由于一些线程问题,我没有足够的经验,看到


以下是设置:

我的主程序在启动时运行,并创建实现自定义界面(IPlayer)的MainWindow窗口的实例。然后,主程序运行一个进程,该进程与IPlayer交互以完成某些任务,其思想是主程序从主窗口请求操作,从而提示用户输入某种类型的内容并显示结果

为了清晰起见,我将简化代码。假设这个程序只是运行一种聊天机器人游戏

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

据我所知,只有两条线索: -主线程-主程序和游戏在此运行。我想这里的窗户也开着,但我可能错了。。。请澄清
-呈现线程-UI在这里呈现。

Argh,这个问题被问了很多次。。。不能从与控件关联的调度程序线程以外的其他线程更新GUI控件。您需要使用运行更新代码来从正确的线程更新GUI


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

听起来您的游戏代码在循环中运行,占用了所有UI的处理时间。听起来你并没有把控制权交给调度员


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

只是…一些.NET线程建议:只更新自己线程上的可视对象。你是不是在一个单独的线程上搞乱了MainWindow?当多线程时,你不能直接从UI线程访问一些东西。哪个对象抛出这个异常?实际上,按照现在编写的方式,我正在尝试从主线程开始执行所有操作。我可能错了,但我认为这是可能的,因为主程序通过调用wdw.Show()启动窗口,然后通过调用game.DoSomething()继续执行。然后,game.DoSomething()将在窗口内调用一个函数,该函数将更改UI并返回一些结果。。。我一定是漏掉了什么……可以解释一下game.RunGame()是如何在不同于人类玩家窗口的线程上运行的吗?@marrithl2:好的,如果您没有使用线thread-thread=new-thread(new-ThreadStart(game.RunGame));那么它就不在另一条线上了。可能您的方法执行时间太长,从而导致GUI挂起。试着用秒表看看。用了秒表,一切似乎都很快。这些方法在Human_Player类上花费的时间不到一毫秒。runGame方法需要一段时间,因为它在两个玩家之间运行整个游戏,不断地在两个玩家之间调用方法。(这实际上是一个战舰游戏)因此,如果runGame方法需要一段时间,这可能是UI挂起的原因。在runGame方法的循环中,攻击之间的时间只有11毫秒。这对我来说似乎不太像,但我不确定要杀死渲染线程需要什么。。。本质上,runGame方法是一个循环,从每个玩家那里获取攻击并检查是否有赢家。这是一个好主意。。。我得调查一下