0

我正在开发一个应用程序,它加载一些 url,解析它们,将它们保存到 sqlite db 中,UI 将读取保存的数据并在控件中显示它们。这一进展应该在几乎无限循环中完成。为了获得快速响应,我计划在主线程中从数据库中读取数据,并让另一个线程(后台工作人员)加载数据并将其插入数据库。在调度程序定时器中运行读写过程是否合乎逻辑并且可能,一个定时器在主线程中,另一个在后台工作者中?如何?或者有人有更好的主意吗?

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
             }
    }
4

2 回答 2

1

你打算做的不会奏效。

您的_Timer1_Tick_Timer2_Tick将在 UI 线程中运行。如果您在那里执行一些长时间运行的操作,它将挂起 UI。

我不明白,你为什么需要计时器?除了测量时间间隔之外,将计时器用于其他任何事情都不是一个好的策略。例如,您可以在后台无限循环中运行更新过程,只要它将新数据放入您调用的数据库Dispatcher.BeginInvoke(传递您想要的任何数据)以通知您的 UI 线程它应该使用新可用的数据更新自身。

顺便说一句,对于像“发送 HTTP 请求、等待响应、解析、存储、重复”这样的任务,新的 async/await 特性是一个自然的选择。对于 WP7,该功能可用作 Visual Studio 2010 的“异步 CTP”可再发行包,对于 WP8,它已集成到框架中。不过,两者之间存在一些兼容性问题。

于 2013-02-11T18:12:29.110 回答
1

加载一些 url,解析它们,将它们保存到 sqlite db 中,UI 将读取保存的数据并在控件中显示它们

请不要那样做。不要创建自己的线程管理系统,只是不要。我并不是说它不会起作用,但它很可能会以最可怕和莫名其妙的方式适得其反。例如,使用 DisptacherTImer 会在您的脸上完全爆炸,因为它在 UI 线程上运行。如果您真的想使用线程,请考虑使用ThreadPool.QueueUserWorkItem()Task.Run()来启动即发即弃的操作。

您的工作流程也很奇怪,我不明白为什么您需要将已经拥有的数据写入数据库,然后将其读回然后才使用它。使用反序列化的数据顺序写入数据库并呈现给 UI 不是更有意义吗?考虑到您已经拥有数据,而不是进行涉及磁盘 I/O 的不必要循环?

您是否考虑过在您的应用程序中使用消息传递?这是一个众所周知的 MVVM 模式,在 MVVM Light 中作为Messenger类和在 PRISM 中作为EventAggregator 实现。在我看来,您的系统有一条“可从服务获得新数据”的消息,并且该消息有两个订阅者:写入数据库和更新 UI。

于 2013-02-12T01:15:50.743 回答