Silverlight 从不通过 WP 8.1 上的调度程序在 UI 线程上执行代码

Silverlight never executing code on UI Thread throught dispatcher on WP 8.1

我的目标是播放一些动画并让 UI 等到它完成后再执行一些其他代码。我有一个 class 这样的:

 class Game
    {
       private string currentClickedCommand;
       private string currentClickedSlot;
       private GamePage gamePage;// gamePage na kojem se vrsi radnja
       private string[] chosenCommands;// ovo je string array u kojem su sadrzana imena odabranih komandi
       private int chapterNumber;
       // Kontekst stranice koristen za update objekata UI

       // Za kontrolu animacija
       public static bool isAnimationComplete;
       private BitmapImage currentImage;

       public Game(GamePage gp, int chapterNum)
       {
           currentClickedCommand = null;
           currentClickedSlot = null;
           gamePage = gp;
           chapterNumber = chapterNum;
           isAnimationComplete = false;
           chosenCommands = new string[5];
           gamePage.characterRectangle.Visibility = System.Windows.Visibility.Collapsed;
           Thread AnimationThread = new Thread(playIntroAnimation);
           AnimationThread.Start();
           while (!isAnimationComplete) { }
           loadCommands();
           loadSlots();
       }

       public void playIntroAnimation() {
               // Pretpostavljam da na osnovu baze znam koja je animacija za ovaj chapter navedena kao uvodna
           Debug.WriteLine("on other thread playing animation");
               // Sakrivam gridove komandi i ostalog

               Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
               {
                   gamePage.CommandGrid.Visibility = System.Windows.Visibility.Collapsed;
                   gamePage.SlotGrid.Visibility = System.Windows.Visibility.Collapsed;
                   MessageBox.Show("Prvi dispatch");
                   Debug.WriteLine("prvi dispatch");
               }));
               // Ucitavam pozadinsku sliku preko canvasa cijelog
               Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
               {
                   ImageBrush bgImage = new ImageBrush();
                   Uri imgSource = new Uri(@"Assets/Chapter backgrounds/chapter_1_introduction.png", UriKind.Relative);
                   BitmapImage img = new BitmapImage(imgSource);
                   bgImage.ImageSource = img;
                   gamePage.mainCanvas.Background = bgImage;
                   MessageBox.Show("Drugi dispatch");
               }));
               // Kreiram parametre animacije
               Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
               {
                   Uri sheetSource = new Uri(@"Assets/Sheets/test_wave_sheet.png", UriKind.Relative);
                   currentImage = new BitmapImage(sheetSource);
                   currentImage.ImageOpened += new EventHandler<RoutedEventArgs>(setAnimationParams);
                   Image i = new Image();
                   i.Source = currentImage;
                   MessageBox.Show("Treci dispatch");
               }));
               // Odredjujem lika i animiram ga -- visinu i sirinu znam iz baze(kad dobavim sheet i ostalo imam gotove parametere
               // sada moram hardkodirat radi testa
               Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
               {
                   gamePage.characterRectangle.Visibility = System.Windows.Visibility.Visible;
                   Canvas.SetLeft(gamePage.characterRectangle, gamePage.mainCanvas.ActualWidth / 4.0);
                   Canvas.SetTop(gamePage.characterRectangle, gamePage.mainCanvas.ActualHeight / 5.0);
                   MessageBox.Show("Cetvrti dispatch");
               }));

       }

       private void setAnimationParams(object sender, RoutedEventArgs e)
       {
           Deployment.Current.Dispatcher.BeginInvoke(() => {
               AnimationClasses.AnimationParams parameters = new AnimationClasses.AnimationParams(currentImage, 462, 438, 7, true, currentImage.PixelWidth, false, 2);
               new AnimationClasses.Animation().Animate(gamePage.characterRectangle, parameters);
           }); 
       }

如您所见,我一直在尝试使用 Deployment.Current... 等方法来做到这一点,但没有成功。我一直在调试,但它根本无法执行这段代码,而且什么也没有发生。

我像这样在页面上创建一个游戏实例:

public GamePage()
        {
            InitializeComponent();


            game = new Game(this,    Convert.ToInt32(PhoneApplicationService.Current.State["chapter"]));

        }

我有一个静态属性 (isAnimationComplete),它在其他地方设置为 true,当动画完成时。 (loadCommands, loadSlots) 之后的 2 个命令需要等待它完成然后执行。 谢谢!

你只是陷入了僵局。

UI 线程正在调用 Game class 的构造函数。在内部,您正在启动一个后台线程,然后循环等待:

while (!isAnimationComplete) { }

这意味着在将 isAnimationComplete 标志设置为 true 之前,UI 线程将无法用于其他操作。这永远不会发生,因为当动画执行完成时你正在这样做......正在等待 UI 线程空闲的动画。