我正在尝试用WPF创建一个图像幻灯片效果。
用新图像更新幻灯片的方法在Windows.Forms.Timer中每隔几秒钟调用一次,并在Task中自己的线程中运行(如下面所示)。
private void LoadImage()
{
Task t = Task.Run(() =>
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
TimeSpan delay = new TimeSpan(0, 0, 0, 0, 0);
Fader.ChangeSource(image, BitmapFromUri(new Uri(compPath + oComps[nCount].name)), delay, delay);
image.Visibility = System.Windows.Visibility.Visible;
mediaElement.Stop();
mediaElement.Close(); ;
mediaElement2.Stop();
mediaElement2.Close();
mediaElement.Visibility = System.Windows.Visibility.Collapsed;
mediaElement2.Visibility = System.Windows.Visibility.Collapsed;
imageLoop.Interval = oComps[nCount].duration;
nCount++;
imageLoop.Start();
}));
});
}同时,在一个覆盖的画布底部有一个滚动的文本横幅。这也是在它自己的线程中运行,通过一个Dispatcher更新UI。
每几个图像,无论是滚动文本还是幻灯片,都会暂停一两秒钟,似乎在等待图像加载。这种行为是意外的,因为每个元素都在一个独立的线程中。
这是否是更新UI线程的两个任务线程之间的冲突?
这可能是什么原因?
发布于 2015-05-28 23:39:37
将工作放在另一个线程上的代码不会将工作放在另一个线程上。您的BeginInvoke将它发送回UI线程,您的所有工作都在那里完成。
在执行BeginInvoke调用之前做大量的工作,这样工作就会在后台线程上实际发生。
private void LoadImage()
{
Task t = Task.Run(() =>
{
//I assume BitmapFromUri is the slow step.
var bitmap = BitmapFromUri(new Uri(compPath + oComps[nCount].name);
//Now that we have our bitmap, now go to the main thread.
this.Dispatcher.BeginInvoke((Action)(() =>
{
TimeSpan delay = new TimeSpan(0, 0, 0, 0, 0);
//I assume Fader is a control and must be on the UI thread, if not then move that out of the BeginInvoke too.
Fader.ChangeSource(image, bitmap), delay, delay);
image.Visibility = System.Windows.Visibility.Visible;
mediaElement.Stop();
mediaElement.Close(); ;
mediaElement2.Stop();
mediaElement2.Close();
mediaElement.Visibility = System.Windows.Visibility.Collapsed;
mediaElement2.Visibility = System.Windows.Visibility.Collapsed;
imageLoop.Interval = oComps[nCount].duration;
nCount++;
imageLoop.Start();
}));
});我怀疑你的横幅实际上也不是在做另一个线程上的工作,你可能想看看它。
如果可能的话,一个更好的解决方法是重写BitmapFromUri,使其成为异步的,并且根本不使用线程。
private async Task LoadImageAsync()
{
TimeSpan delay = new TimeSpan(0, 0, 0, 0, 0);
var bitmap = await BitmapFromUriAsync(new Uri(compPath + oComps[nCount].name);
Fader.ChangeSource(image, bitmap), delay, delay);
image.Visibility = System.Windows.Visibility.Visible;
mediaElement.Stop();
mediaElement.Close(); ;
mediaElement2.Stop();
mediaElement2.Close();
mediaElement.Visibility = System.Windows.Visibility.Collapsed;
}https://stackoverflow.com/questions/30518760
复制相似问题