我有一个程序可以测试windows图像中的各种设置。每个测试都标记为“插件”。现在我的所有插件都使用ThreadPool.QueueUserWorkItem在工作线程中运行。
当我们想要用户输入测试时他/她必须测试设备的声音/视频和触摸屏时出现问题。为了测试这个,我在我的一个插件类中创建了一个辅助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时遇到问题。 / p>
'numberofrunningthreads'仅用于debug.print目的。
非常感谢任何帮助,如果您需要更多代码段,或者我不清楚任何事情,请询问,我会尽快回复。
答案 0 :(得分:0)
终于弄清楚出了什么问题。我一直在关注这个事实,我认为我的控制线程有错误。它似乎是测试需要运行的设备上的CPU问题。看来有时如果没有足够的CPU可用,就不会创建MediaElement,所以我使用的测试视频质量太高,所以它只在某些时候工作,并且出于某种原因,CPU使用率是第二次测试运行时总是略低一点。
我会留下问题以防其他人碰巧没有加载MediaElement的问题。我使用这个程序来强调我的CPU,所以我可以让我的程序“崩溃”MediaElement来验证它是在CPU负载太高而不会创建元素的时候。 (取决于视频的质量)
http://alax.info/blog/1342/comment-page-1
这有助于我得出结论,当用户使用多个MediaElements并遇到与我相同的问题时,上述软件也被另一个用户'Roman R'链接:Black video using multiple instances VMR 9