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 スレッドでコードを実行し、「StoryBoard」にアクセスできます。たとえば、コード ビハインドで 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

DependencyObjects には、それらを作成したスレッドからのみアクセスできます。あなたの場合、UI 要素はメイン UI スレッドからのみアクセスできます。

を使用Dispatcher.BeginInvokeして、メイン UI スレッドのディスパッチャでデリゲートを呼び出すことができます。UserControl または Window から Dispatcher オブジェクトを取得できます。一般に、すべての UI 要素にはDispatcherプロパティが必要です。

于 2012-10-05T07:15:12.257 に答える