[英]WPF UI Freezes - UI Thread conflict?
我正在嘗試使用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線程的Task線程之間的沖突嗎?
是什么原因造成的?
您將代碼放在另一個線程上的代碼不會將工作放在另一個線程上。 您的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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.