我正在开发一个加载一些url的应用程序,解析它们,将它们保存到sqlite db中,UI将读取保存的数据并在控件中显示它们。应该在几乎无限循环中完成这一进展。为了获得快速响应,我计划从主线程中的db读取数据,并有另一个线程(后台工作者)来加载数据并将其插入到db中。是否合乎逻辑且可以在dispatchertimer中运行读写过程,主线程中的一个计时器和后台工作程序中的另一个计时器?如何?或者有没有人有更好的想法?
main thread:
DispatcherTimer _Timer1 = new DispatcherTimer();
_Timer1.Interval = _Interval;
_Timer1.Tick += _Timer1_Tick;
void _Timer1_Tick(object sender, EventArgs e)
{
// read data from db and show in controls
}
secondary thread:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
DispatcherTimer _Timer2 = new DispatcherTimer();
_Timer2.Interval = _Interval;
_Timer2.Tick += _Timer2_Tick;
}
void _Timer2_Tick(object sender, EventArgs e)
{
// write data into db
}
}
答案 0 :(得分:1)
你打算做什么不会工作。
您的_Timer1_Tick
和_Timer2_Tick
都将在UI线程中运行。如果你在那里执行一些长时间运行的操作,它将挂起UI。
我不明白,为什么你需要计时器?除了测量时间间隔之外,使用计时器是很好的策略。你可以,例如在后台的无限循环中运行更新过程,只要它将新数据放入您调用Dispatcher.BeginInvoke
的数据库(传递您想要的任何数据)以通知您的UI线程,它应该使用新的可用数据更新自己。
顺便说一句,对于“发送HTTP请求,等待响应,解析,存储,重复”等任务,新的异步/等待功能是一个自然的选择。对于WP7,该功能可用作Visual Studio 2010的“Async CTP”可再发行组件包,对于WP8,它已经集成到框架中。但是,2之间存在一些兼容性问题。
答案 1 :(得分:1)
加载一些url,解析它们,将它们保存到sqlite db中,UI将读取保存的数据并在控件中显示它们
请不要那样做。不要创建自己的线程管理系统,只是不要。我并不是说它不起作用,但它最有可能以最可怕和最令人费解的方式适得其反。例如,使用DisptacherTImer完全爆炸,因为它在UI线程上运行。如果你真的想使用线程考虑ThreadPool.QueueUserWorkItem()或Task.Run()来启动即发即弃操作。
您的工作流程也很奇怪,我不明白为什么您需要将已有的数据写入数据库,然后再读回来然后再使用它。使用反序列化数据将其顺序写入数据库并将其呈现给UI是否更有意义?考虑到你已经拥有数据,而不是做涉及磁盘I / O的不必要的循环?
您是否考虑在应用中使用Messaging?这是一个非常着名的MVVM模式,在MVVM Light中作为Messenger类实现,在PRISM中作为EventAggregator实现。在我看来,您的系统有一条消息“可以从服务中获得新数据”,该消息有两个订阅者:写入数据库并更新UI。