C# 异步while循环更新可观察集合

C# 异步while循环更新可观察集合,c#,wpf,loops,asynchronous,data-binding,C#,Wpf,Loops,Asynchronous,Data Binding,我写的程序有问题。我想要的是一个循环,只要程序在运行,就可以运行,时间跨度为30秒。我希望这个循环更新一个ObservableCollection,这样当有新的新闻时,新闻就会显示在窗口的顶部 我已经删去了代码,所以只有最重要的部分供你处理。如果这个代码能够工作,我会在添加的可观察的新闻集合中看到一个新项目。然而,这不是它的工作原理。用这个代码我只得到第一个 少了什么 public MainWindow() { InitializeComponent(); ObservableC

我写的程序有问题。我想要的是一个循环,只要程序在运行,就可以运行,时间跨度为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主窗口()
{
初始化组件();
ObservableCollection列表=新的ObservableCollection();
Task.Factory.StartNew(()=>LoopFunction(list));
NewsListView.ItemsSource=list.OrderByDescending(a=>a.Date);
}
公共ObservableCollection循环函数(ObservableCollection列表)
{
while(true)
{
list.Add(newnews(){Date=“2016-12-12”,From=“DIRECT:”,Title=“此程序不工作”,Content=“我们必须修复它。”});
睡眠(30000);
}
}
公共类新闻
{
公共字符串日期{get;set;}
来自{get;set;}的公共字符串
公共字符串标题{get;set;}
公共字符串内容{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; }
}
public主窗口()
{
初始化组件();
ObservableCollection列表=新的ObservableCollection();
//在程序启动时获取新闻
新闻(列表);
//每30秒获取一次新闻
调度程序计时器=新调度程序();
timer.Interval=时间跨度(从秒开始)(30);
timer.Tick+=(s,args)=>FetchNews(列表);
timer.Start();
}
公共新闻(可观察收集列表)
{
list.Add(newnews(){Date=“2016-12-12”,From=“DIRECT:”,Title=“此程序正在运行”,Content=“我们已经修复了它。”});
NewsListView.ItemsSource=list.OrderByDescending(a=>a.Date);
}
公共类新闻
{
公共字符串日期{get;set;}
来自{get;set;}的公共字符串
公共字符串标题{get;set;}
公共字符串内容{get;set;}
}

只需使用Dispatchermer,而不是像mike所说的那样,在使用OrderByDescending时异步执行任何操作,NewsListView不会收到“列表”集合更改的通知

如果你使用

NewsListView.ItemsSource = list;
在非UI线程中更新集合时,仍然会出现异常。但是,如果您使用的是.NET 4.5,则可以在非UI线程中更新集合,您需要执行以下操作:

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

主要问题是OrderByDescending返回一个新的可枚举项,该可枚举项在枚举时进行排序,但它不向视图提供集合更改事件。视图不知道应该更新它。另一个可能出现的问题是绑定到视图的ObservableCollection必须在UI线程上更新。LoopFunction不返回ObservableCollection。您需要并发OC,但没有并发OC。尽管如此,我认为这是行不通的。不确定你想在这里做什么,但寻找另一种方法。
private object listLock = new object();