我正在构建一个单窗口WPF应用程序 在窗口中是一个列表项(当然会保存在数据库中) 我需要定期启动一个后台任务,从Atom提要中更新数据库。当每个新项目添加到数据库时,UI中的列表也必须更新以反映这一点。我不希望这个后台任务减慢UI的速度,但同时它需要与UI进行交互。
阅读了大量文章并看到了很多简单的例子,我仍然不确定实现这一点的最佳方法。
我认为我可以做的是:
在Window_Loaded事件上,创建DispatchTimer。 触发Tick事件时,调用UpdateDb()方法。 UpdateDB()将从Atom提要中获取项目并添加到数据库中。当我遍历每个项目时,我将调用另一个方法将列表重新绑定到数据库,以便“刷新”。 完成所有任务后重置DispatchTimer ??? (不确定是否可以/需要/完成)。
请记住,这是后台任务,因此用户可以同时使用UI。
这听起来怎么样?
感谢。
答案 0 :(得分:2)
这听起来不是最理想的,因为您在UI线程上进行数据库连接。当Tick
事件在DispatcherTimer
上触发时,处理程序将在UI线程上执行。您需要最小化在此线程上执行的工作量以保持UI响应,并且您绝对不应该在此线程上执行IO绑定工作。
我可能有一个数据服务,其职责是更新数据库并在进行更改时引发事件。您的UI图层可以附加到这些事件并编组到UI线程以应用更改。要编组到UI线程,您只需要调用Dispatcher.Invoke
。
无论您采用何种具体方法,关键是在单独的线程上尽可能多地(包括任何数据库访问)。 Marshal尽可能晚地回到UI线程,并尽可能少地在UI线程上工作。
另外需要注意的是,WPF会自动为您更改标量值。您只需要对集合进行编组更改(添加/删除/替换项目)。
答案 1 :(得分:0)
你的方法会奏效。
当应用加载时,您将启动计时器。对于计时器的每个刻度,您启动一个线程来更新数据库。一旦数据库更新发生,您可以在UI对象上调用.BeginInvoke()
来更新演示文稿线程上的UI(这将是您的UI应该受到影响的唯一时间)。
答案 2 :(得分:0)
我使用System.Threading.Timer,它将在线程池线程上以指定的时间间隔调用指定的方法,因此无需创建额外的线程,让数据库使用它并编组回ui线程根据需要。
答案 3 :(得分:0)
WPF Multithreading with BackgroundWorker:
好消息是你真的不必编写这样的组件,因为已经有了一个组件:.Net Framework 2.0中引入的
BackgroundWorker
类。熟悉WinForms 2.0的程序员可能已经使用过这个组件。但BackgroundWorker
与WPF同样适用,因为它与线程模型完全无关。