我正在写一个监控的图形用户界面应用程序,我想得到一些关于它的逻辑的建议基本上,应用程序需要做的就是每x分钟连接到一个远程服务器,检查是否有更改,如果有更改,就获取更改,并根据更改执行操作(根据更改更新本地数据库等)。
我的第一个想法是:
有一个复选框(监视开/关)。单击(如果选中)将启动计时器。
计时器在其tick方法中启动backgroundworker。
dowork方法做连接/检索信息的工作
a)on WorkDone处理程序方法从后台工作程序获取信息并用它进行本地更新
b)在workdone中,handler方法根据其得到的更改触发一个或多个自定义事件somethingchanged;eventlisteners从那里处理本地更新。
我的主要问题是从timer调用worker,因为我向表单添加了worker,现在它们在不同的线程上(这是正确的描述吗?)然后传递结果也是一个类似的问题我读了一些关于代表的文章,但仍然不确定何时、如何使用,以及是否首先需要使用我需要BGWorker和Timer吗?我需要自定义事件还是只需要在WorkOne中使用开关(result)就可以完成所有工作?这个基本原则一开始是好的吗,也许有更好的东西,我正在重新发明轮子?提前谢谢你!

最佳答案

从架构的角度来看:
消息队列分离应用程序的位在windows窗体中,应用程序可以依赖windows为您创建和管理的消息队列。Google for PostMessage/GetMessage等,这通常称为“消息传递”。
典型的电弧结构
应用程序的一部分将请求“推送到”队列中
应用程序的其他部分从队列“拉”出请求,并将结果写入第二个队列。
然后,第一部分可以从第二个“结果”队列“拉”出请求并显示给用户。
看起来是这样的:
应用-->请求队列-->处理引擎-->结果队列-->应用
处理引擎可以在同一个应用程序、同一个线程或不同的线程/进程(甚至不同的机器)中。
可以使用简单队列:比如说Queue<string>()(只要使用锁访问它)或增加复杂性或越来越多的复杂/功能队列。
幼稚策略和其他解决方案的问题需要考虑的事情:
如果您在旧请求尚未完成时提出新请求,会发生什么情况?
如果发生错误怎么办?是否要内联错误您可以使用另一个队列来处理错误吗?
你想再试一次吗?
如果信息丢失了怎么办?(即请求被推送,但没有响应…)有事务队列等。
示例代码

    object oLock = new object();
    Queue<string> requests = new Queue<string>();
    Queue<string> responses = new Queue<string>();
    Thread mThread;
    AutoResetEvent mEvent = new AutoResetEvent(false);

    public Form1()
    {
        InitializeComponent();
        mThread = new Thread(ProcessingEngine);
        mThread.IsBackground = true;
        mThread.Start();
    }

    private void ProcessingEngine()
    {
        string result;
        string request = null;

        while (true)
        {
            try
            {
                mEvent.WaitOne();

                lock (oLock)
                {
                    request = requests.Dequeue();
                }

                var wc = new WebClient();
                result = wc.DownloadString(request);

                lock (oLock)
                {
                    responses.Enqueue(result);
                }
            }
            catch (Exception ex)
            {
                lock (oLock)
                {
                    responses.Enqueue(ex.ToString());
                }
            }
        }
    }


    private void timer1_Tick(object sender, EventArgs e)
    {
        lock (oLock)
        {
            //Stick in a new request
            requests.Enqueue("http://yahoo.com");

            //Allow thread to start work
            mEvent.Set();

            //Check if a response has arrived
            if (responses.Any())
            {
                var result = responses.Dequeue();
                listBox1.Items.Add(result.Substring(1,200));
            }
        }
    }
}

09-25 18:25
查看更多