Tôi mới sử dụng đa luồng và WPF.Cập nhật không đồng bộ cho các mục ObservableCollection
Tôi có một ObservableCollection<RSSFeed>
, tại mục khởi động ứng dụng được thêm vào bộ sưu tập này từ chuỗi giao diện người dùng. Các thuộc tính của RSSFeed được liên kết với ListView WPF. Sau đó, tôi muốn cập nhật từng RSSFeed một cách không đồng bộ. Vì vậy, tôi đang nghĩ đến việc triển khai một cái gì đó như RSSFeed.FetchAsync()
và nâng cao PropertyChanged trên các thuộc tính được cập nhật của nó.
Tôi biết rằng ObservableCollection không hỗ trợ cập nhật từ các chủ đề khác ngoài chuỗi giao diện người dùng, nó ném NotSupportedException. Nhưng kể từ khi tôi không thao tác ObservableCollection chính nó nhưng thay vì cập nhật tài sản trên các mặt hàng của nó, tôi có thể mong đợi điều này để làm việc và xem các mục ListView cập nhật? Hoặc nó sẽ ném một ngoại lệ anyway do PropertyChanged?
Edit: đang
RSSFeed.cs
public class RSSFeed
{
public String Title { get; set; }
public String Summary { get; set; }
public String Uri { get; set; }
public String Encoding { get; set; }
public List<FeedItem> Posts { get; set; }
public bool FetchedSuccessfully { get; protected set; }
public RSSFeed()
{
Posts = new List<FeedItem>();
}
public RSSFeed(String uri)
{
Posts = new List<FeedItem>();
Uri = uri;
Fetch();
}
public void FetchAsync()
{
// call Fetch asynchronously
}
public void Fetch()
{
if (Uri != "")
{
try
{
MyWebClient client = new MyWebClient();
String str = client.DownloadString(Uri);
str = Regex.Replace(str, "<!--.*?-->", String.Empty, RegexOptions.Singleline);
FeedXmlReader reader = new FeedXmlReader();
RSSFeed feed = reader.Load(str, new Uri(Uri));
if (feed.Title != null)
Title = feed.Title;
if (feed.Encoding != null)
Encoding = feed.Encoding;
if (feed.Summary != null)
Summary = feed.Summary;
if (feed.Posts != null)
Posts = feed.Posts;
FetchedSuccessfully = true;
}
catch
{
FetchedSuccessfully = false;
}
}
}
UserProfile.cs
public class UserProfile : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public event CollectionChangeEventHandler CollectionChanged;
private ObservableCollection<RSSFeed> feeds;
public ObservableCollection<RSSFeed> Feeds
{
get { return feeds; }
set { feeds = value; OnPropertyChanged("Feeds"); }
}
public UserProfile()
{
feeds = new ObservableCollection<RSSFeed>();
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
protected void OnCollectionChanged(RSSFeed feed)
{
CollectionChangeEventHandler handler = CollectionChanged;
if (handler != null)
{
handler(this, new CollectionChangeEventArgs(CollectionChangeAction.Add, feed));
}
}
}
MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
// My ListView is bound to this
// ItemsSource="{Binding Posts}
public List<FeedItem> Posts
{
get
{
if (listBoxChannels.SelectedItem != null)
return ((RSSFeed)listBoxChannels.SelectedItem).Posts;
else
return null;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// here I load cached feeds
// called from UI thread
// now I want to update the feeds
// since network operations are involved,
// I need to do this asynchronously to prevent blocking the UI thread
}
}
Cảm ơn.
Cảm ơn. Tôi có một bộ sưu tập lồng nhau trong lớp RSSFeed của tôi. Nó sẽ là một soulution tốt nếu RSSFeed.FetchAsync() nêu ra một sự kiện về hoàn thành của nó và trả về mới (cập nhật) RSSFeed dụ thông qua EventArgs? Sau đó tôi sẽ cập nhật mục tương ứng trong bộ sưu tập từ chuỗi giao diện người dùng. – Martin
Đó là một giải pháp khả thi. Nếu chúng ta có thể thấy một số mã tôi có thể cung cấp cho bạn một câu trả lời cụ thể hơn. –
@malymato thường Các phương pháp Async cung cấp gọi lại khi hoàn tất. Bạn đang sử dụng loại triển khai nào? –