异步while循环更新observable集合

时间:2016-01-15 19:01:21

标签: c# wpf loops asynchronous data-binding

我遇到了一个我正在编写的程序的问题。我想要的是一个循环,只要程序运行就会运行,循环时间为30秒。我希望这个循环更新一个ObservableCollection,以便当有一个新的时候,新闻显示在窗口的顶部。

我已经删除了代码,因此只有最重要的部分才能供您处理。如果这段代码有效,我会在新闻的可观察集合中看到一个新项目。然而,这不是它的工作原理。使用此代码我只得到第一个。

缺少什么?

public MainWindow()
{
    InitializeComponent();
    ObservableCollection<News> list = new ObservableCollection<News>();
    Task.Factory.StartNew(() => LoopFunction(list));
    NewsListView.ItemsSource = list.OrderByDescending(a => a.Date);
}
public ObservableCollection<News> LoopFunction (ObservableCollection<News> list)
{
    while (true)
    {
        list.Add(new News() { Date = "2016-12-12", From = "DIRECT:", Title = "This program is not working", Content = "We have to fix it." });
        Thread.Sleep(30000);
    }
}
public class News
{
    public string Date { get; set; }
    public string From { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

感谢您的所有意见。这是我如何运作的。

public MainWindow()
{
    InitializeComponent();
    ObservableCollection<News> list = new ObservableCollection<News>();

    // Fetches news when the program initiates
    FetchNews(list);

    // Fetches news every 30 seconds
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromSeconds(30);
    timer.Tick += (s, args) => FetchNews(list);
    timer.Start();
}
public void FetchNews (ObservableCollection<News> list)
{
    list.Add(new News() { Date = "2016-12-12", From = "DIRECT:", Title = "This program is working", Content = "We have fixed it." });
    NewsListView.ItemsSource = list.OrderByDescending(a => a.Date);
}
public class News
{
    public string Date { get; set; }
    public string From { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

2 个答案:

答案 0 :(得分:0)

只需使用DispatcherTimer而不是做任何异步

答案 1 :(得分:0)

正如迈克所说,当你使用OrderByDescending时,NewsListView没有被通知&#39;列表&#39;收藏改变了。

如果您使用

NewsListView.ItemsSource = list;

在非UI线程中更新集合时,仍会出现异常。但是,是的,如果你使用的是.NET 4.5,你可以在非UI线程中更新集合,你需要做的就是关注,

    ObservableCollection<News> list = new ObservableCollection<News>();
    BindingOperations.EnableCollectionSynchronization(list, listLock);

并且您还需要在类的某处定义锁变量

private object listLock = new object();