मैं multithreading और WPF के लिए नया हूँ।अवलोकन करने योग्य चयन वस्तुओं के लिए असीमित अद्यतन
मेरे पास ObservableCollection<RSSFeed>
है, ऐप स्टार्टअप आइटम UI संग्रह से इस संग्रह में जोड़े गए हैं। आरएसएसएफआईडी की संपत्तियां डब्ल्यूपीएफ लिस्ट व्यू से जुड़ी हैं। बाद में, मैं प्रत्येक आरएसएसफ़ीड को असीमित रूप से अपडेट करना चाहता हूं। तो मैं RSSFeed.FetchAsync()
जैसे कुछ को लागू करने और इसके अद्यतन गुणों पर PropertyChanged को बढ़ाने के बारे में सोच रहा हूं।
मुझे पता है कि ObservableCollection UI थ्रेड के अलावा थ्रेड से अपडेट का समर्थन नहीं करता है, यह NotSupportedException फेंकता है। लेकिन चूंकि मैं ऑब्जर्जेबल कोलेक्शन में खुद को जोड़ नहीं रहा हूं बल्कि इसकी वस्तुओं पर गुणों को अपडेट कर रहा हूं, क्या मैं इसे काम करने की उम्मीद कर सकता हूं और ListView आइटम अपडेट कर सकता हूं? या संपत्ति के कारण किसी भी तरह से अपवाद फेंक दिया जाएगा?
संपादित करें: कोड
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
}
}
धन्यवाद।
धन्यवाद का उल्लेख कर सकते हैं। मेरे आरएसएसफ़ीड कक्षा में मेरा घोंसला संग्रह है। अगर यह आरएसएसएफआईडी.फेटाएसिंक() ने अपना पूरा होने पर एक कार्यक्रम उठाया और इवेंटअर्ज़ के माध्यम से नया (अपडेटेड) आरएसएसफाइड उदाहरण वापस कर दिया तो क्या यह एक अच्छा आत्मविश्वास होगा? बाद में मैं UI थ्रेड से संग्रह में संबंधित आइटम अपडेट कर दूंगा। – Martin
यह एक संभावित समाधान है। अगर हम कुछ कोड देख सकते हैं तो मैं आपको एक और ठोस जवाब दे सकता हूं। –
@malymato आमतौर पर Async विधियां पूर्ण होने पर कॉलबैक प्रदान करती हैं। आप किस प्रकार के कार्यान्वयन का उपयोग कर रहे हैं? –