Silverlight永远不会在WP 8.1上的调度程序上执行UI线程上的代码

时间:2015-02-19 14:38:26

标签: c# multithreading silverlight windows-phone-8

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

 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 ......等但是没有运气。我一直在调试,但它根本不会执行此代码,也没有发生任何事情。

我在页面上创建了一个Game的实例:

public GamePage()
        {
            InitializeComponent();


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

        }

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

1 个答案:

答案 0 :(得分:1)

你只是陷入僵局。

UI线程正在调用Game类的构造函数。在里面,你开始一个后台线程,然后在循环中等待:

while (!isAnimationComplete) { }

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