[英]List box selection with time consuming task that needs to update the UI
當用戶為列表框選擇一個項目時,我有一個執行耗時任務的應用程序。
當用戶選擇一個節目時,應用程序將從tvdb中檢索所有節目信息,並將其顯示在Ui中。
當節目仍在加載時用戶快速更改選擇時,就會出現問題。
我想這樣做,以便用戶可以改變主意,然后在第一次加載時進行另一個選擇,並將該信息顯示在Ui中。
我創建了一個簡單的演示應用程序來演示該問題: 演示應用程序 。
這就是我試圖做的
列表框選擇事件處理程序
private void lb1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string sid = lb1.SelectedItem.ToString();
try
{
LoadSeries(Int32.Parse(sid));
}
catch (FormatException)
{
MessageBox.Show("Please enter a valid series id");
}
}
負載系列
private void LoadSeries(int _seriesId)
{
Task<TvdbSeries> series = Task.Factory.StartNew(() =>
{
TvdbSeries seriesloaded = null;
try
{
seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
}
catch (TvdbInvalidApiKeyException ex)
{
MessageBox.Show(ex.Message);
}
catch (TvdbNotAvailableException ex)
{
MessageBox.Show(ex.Message);
}
return seriesloaded;
}
);
series.ContinueWith((antecedent) =>
{
UpdateSeries(series.Result);
},
TaskScheduler.FromCurrentSynchronizationContext()
);
}
如果用戶快速更改選擇,則在seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
的行上出現應用程序錯誤seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
並在調試器中顯示此消息“ WebClient不支持並發I / O操作。 ”
我確實發現這是因為我在最后一個請求完成之前發出了一個新請求,但是我無法在m_tvdbHandler.GetSeries中鏈接代碼,因為它的功能來自我正在使用的庫,並且有人寫過。
這是庫tvdblib ,我確定問題出在我做事的方式而不是庫。
當用戶進行選擇時,可以禁用UI,直到信息完全加載,並在底部加載時顯示一條消息,請等待。 加載完所有內容后,啟用Ui並隱藏消息。
您將此問題作為C#5.0問題發布,因此應盡可能多地使用async
/ await
。
private Task<TvdbSeries> LoadSeriesAsync(int _seriesId)
{
return Task.Run(() =>
{
TvdbSeries seriesloaded = null;
try
{
seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
}
catch (TvdbInvalidApiKeyException ex)
{
MessageBox.Show(ex.Message);
}
catch (TvdbNotAvailableException ex)
{
MessageBox.Show(ex.Message);
}
return seriesloaded;
}
);
}
如果有一個LoadSeriesAsync
會更好。
一種方法是在檢索序列時禁用lb1 。
私有異步void lb1_SelectionChanged(對象發送方,SelectionChangedEventArgs e){字符串sid = lb1.SelectedItem.ToString();
try
{
lb1.IsEnabled = false;
var series = await LoadSeriesAsync(Int32.Parse(sid));
UpdateSeries(series);
}
catch (FormatException)
{
MessageBox.Show("Please enter a valid series id");
lb1.IsEnabled = true;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.