2015-09-04 101 views
0

我有一个应用程序,应该测试Windows图像中的各种设置。每个测试都被标记为“插件”。现在我所有的插件都使用ThreadPool.QueueUserWorkItem在工作线程中运行。WPF次要UI线程MediaElement不会加载第一次运行

当我们需要用户输入测试,他/她必须测试设备的声音/视频和触摸屏时,发生了一个问题。为了测试这个,我在我的一个插件类中创建了一个辅助WPF窗口,所以这个插件打开了这个窗口,等待用户输入然后关闭。该窗口由一个标签,3个单选按钮和一个MediaElement按钮组成。

当我打开我的应用程序时,它会加载所有的.dll文件,然后我可以选择按下我的“运行测试”按钮,该按钮运行我的插件列表并运行它们。

现在因为我们需要这个用户交互线程,所以我需要它与ThreadPool线程不同。下面的代码显示了我如何开始我的所有线程,第一部分是用户交互插件。该代码是凌乱的,因为我现在已经测试了几种解决方案,有些我试图将其纳入其他..

if (availablePlugin.RequirementNumber.Equals("13996")) 
      { 
      try 
      { 
       plugin.Status = VerdictEnum.InProgress; 
//    var uiThread = new Thread(plugin.TestMethod); 

       Action startUIThread =() => 
       { 
       Thread uiThread = new Thread(new ThreadStart(() => 
       { 
        SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)); 
        plugin.TestMethod(); 
       })); 

       uiThread.SetApartmentState(ApartmentState.STA); 
       uiThread.IsBackground = true; 
       uiThread.Start(); 
       uiThread.Join(); 
       }; 
       Dispatcher.CurrentDispatcher.Invoke(startUIThread); 
      } 
      catch (Exception ex) 
      { 
       uiContext.Post(
       (o) => plugin.ErrorDescription += "Test case threw an unexpected exception: " + ex.Message, null); 
       uiContext.Post((o) => plugin.Status = VerdictEnum.Inconclusive, null); 
      } 
      finally 
      { 
       //Once the thread has finished it sets its personal ManualResetEvent to true, indicating it has finished its job 
       numberOfRunningThreads--; 
       eventlist[localCounter].Set(); 
       Debug.Print("TEST ENDED"); 
      } 
      } 
      //All other tests are created as worker threads using the ThreadPool. 
      else 
      { 
      ThreadPool.QueueUserWorkItem(
       new WaitCallback(s => 
       { 
       try 
       { 
        plugin.Status = VerdictEnum.InProgress; 
        plugin.TestMethod(); 
       } 
       catch (Exception ex) 
       { 
        uiContext.Post(
        (o) => plugin.ErrorDescription += "Test case threw an unexpected exception: " + ex.Message, null); 
        uiContext.Post((o) => plugin.Status = VerdictEnum.Inconclusive, null); 
       } 
       finally 
       { 
        //Once the thread has finished it sets its personal ManualResetEvent to true, indicating it has finished its job 
        numberOfRunningThreads--; 
        eventlist[localCounter].Set(); 
        Debug.Print("TEST ENDED"); 

       } 
       })); 
      } 

我如何呈现插件类在我的窗口一看:

 var videoAudioTest = new VideoAudioPopup(); 
     videoAudioTest.Show(); 
     videoAudioTest.ResultReady += videoAudioTest_ResultReady; 

     //  videoAudioTest.Closed += (s, e) => System.Windows.Threading.Dispatcher.ExitAllFrames(); 
     //  videoAudioTest.Closed += (s, e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); 
     videoAudioTest.Closed += (s, e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); 


     Dispatcher.Run(); 

这里来了有趣的部分。当我在我的电脑上运行这个测试时,所有的工作都没有任何问题。我从来没有无法加载我的MediaElement。当我在需要测试的设备上运行我的应用程序时,它将(几乎有几次)从不在第一次运行(第一次按'运行测试'按钮)时运行。如果我保持应用程序打开,并再次按下'运行测试'按钮,它总是有效。

它为MediaElement加载的视频是W7标准afaik'Wildlife.wmv'。媒体播放器本身在外部运行时不会出现任何问题。

我认为这是因为我搞乱了我的线程? - 据说现在的代码有点麻烦,我尝试了一些在我的计算机上工作的其他方法,但它们在设备上从来没有像预期的那样工作,它们几乎总是在新窗口中加载MediaElement时遇到问题。

'numberofrunningthreads'只存在于debug.print目的中。

任何帮助非常感谢,如果您需要更多的代码片段,或者如果我什么都不清楚,请问,我会尽快回复。

回答

0

终于明白出了什么问题。我一直关注的事实是,我认为自己控制自己的线程有问题。这似乎是测试需要运行的设备上的CPU问题。看起来有时如果MediaElement没有足够的可用CPU,它将不会被创建,所以我使用的测试视频的质量太高了,所以它只能工作一些时间,并且由于某些原因,CPU使用率第二次测试运行时总是略低一点。

如果有人碰巧遇到MediaElement未加载问题,我会留下问题。我使用这个程序来强调我的CPU,所以我可以可靠地让我的程序'崩溃'的MediaElement来验证它是当CPU负载太高,它不会创建元素。 (根据视频的质量)

http://alax.info/blog/1342/comment-page-1

帮我我的结论,一个用户使用多个MediaElements何时遇到同样的问题,因为我在上面的软件也被环环相扣用户'Roman R':Black video using multiple instances VMR 9

相关问题