0

我正在尝试用 C#/XAML 制作一个简单的游戏。我有一个工作线程,它计算每个刻度的游戏元素的新位置,然后用新位置更新 UI。或者至少应该是。

相反,输出显示:

A first chance exception of type 'System.Exception' occurred in Game.exe
An exception of type 'System.Exception' occurred in Game.exe but was not handled in user code
The thread '<No Name>' (0x1218) has exited with code 0 (0x0).

我已经用断点筛选了这个,代码在这个区域中断了。

        //Stop previous animation in case it is ongoing
        GameStoryboard.Stop();

        //Remove all previous timelines from the storyboard
        foreach (Timeline timeline in GameStoryboard.Children)
        {
            GameStoryboard.Children.Remove(timeline); 
        }

那里的第一行代码使它崩溃,但我可以注释掉 GameStoryboard.Stop() 行(它仅在游戏的滴答时间在循环之间自动降低的情况下才相关),然后它只是在 foreach 循环上崩溃。如果我注释掉 foreach 循环,它会在我下次引用 GameStoryboard 时崩溃。

GameStoryboard 的声明如下所示:

        <Canvas Name="GameCanvas" Height="900" Width="1440" Background="Blue">
            <Canvas.Resources>
                <Storyboard x:Name="GameStoryboard"/>
            </Canvas.Resources>
        </Canvas>

我能想到的唯一理论是,XAML 对象是否不允许您从与初始化它的线程不同的线程引用它们?如果是这样,做我想做的最好的方法是什么?如果没有,有人知道是什么原因造成的吗?

4

2 回答 2

3

正如 Alex 所说,您只能从创建它们的线程访问 DependencyObjects。

您可以使用 Dispatcher 在 UI 线程上执行代码以访问您的“故事板”。例如,如果您在代码隐藏中使用 BackgroundWorker:

private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
    Dispatcher.BeginInvoke(new Action(ClearChildren), DispatcherPriority.Normal);
}

private void ClearChildren()
{
    GameStoryBoard.Children.Clear();
}
于 2012-10-05T07:33:58.043 回答
2

您只能从创建它们的线程访问 DependencyObject。在您的情况下,只能从主 UI 线程访问 UI 元素。

您可以使用Dispatcher.BeginInvoke在主 UI 线程的调度程序上调用委托。您可以从 UserControl 或 Window 中获取 Dispatcher 对象,通常每个 UI 元素都应该有一个Dispatcher属性。

于 2012-10-05T07:15:12.257 回答