试图了解日志阅读器

时间:2010-12-02 12:16:34

标签: c# delegates begininvoke sta

我想了解一些代码。这是一个打印日志数据的小程序。它是通过创建一个由DataTable填充的DataGridView的表单来完成的。表单类还具有刷新功能(RefreshPresentation)。 BusinessLogic类执行更新DataTable并在表单中调用refresh函数的实际工作。所以我非常了解功能,但不是为什么程序的结构是这样的。

  1. 为什么businessLogic.DoWork作为一个 线程而不仅仅是普通的方法调用?
  2. 有人可以解释一下 RefreshPresentation功能对我来说? (BeginInvoke和委托)
  3. 将MainForm作为参数传递给BusinessLogic是一个好主意/做法吗?
  4. 这是该应用程序的主要入口点。

    public class Program
        {
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new MainForm());            
            }
        }
    

    这是表格的相关部分。

    public partial class MainForm : Form
    {
        private BusinessLogic businessLogic;
        private DataTable viewDataTable;
    
        public MainForm()
        {
            InitializeComponent();
    
            businessLogic = new BusinessLogic(this);
            Thread t = new Thread(new ThreadStart(businessLogic.DoWork));
            t.Start();
        }
    
        public delegate void RefreshPresentationDelegate(DataTable dataTable);
    
        public void RefreshPresentation(DataTable dataTable)
       {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new RefreshPresentationDelegate(RefreshPresentation), new object[] { dataTable });
                return;
            }
    ...
    

    这是业务逻辑。

    internal class BusinessLogic
        {
            private MainForm form;
            private Logging.DAL.Logger loggerDAL;
            private int lastId;
    
            internal DataTable DataTable { get; private set; }
            internal bool IsRunning { get; set; }
    
            public BusinessLogic(MainForm form)
            {
                this.form = form;
                this.loggerDAL = new Logging.DAL.Logger();
                this.IsRunning = true;
                DataTable = new DataTable();
            }
    
            public void DoWork()
            {
                while (this.IsRunning)
                {
                    // Get new log messages.
                    if (DataTable.Rows.Count > 0)
                        this.lastId = (int)DataTable.Rows[DataTable.Rows.Count - 1]["Id"];
    
                    this.DataTable = loggerDAL.GetLogMessagesSinceLastQuery(lastId);
    
                    // Callback to GUI for update.
                    form.RefreshPresentation(this.DataTable);
    
                    // Wait for next refresh.
                    Thread.Sleep(1000);
                }
            }
    
        }
    

2 个答案:

答案 0 :(得分:2)

Q1。为什么businessLogic.DoWork作为线程运行而不仅仅是普通的方法调用?

A1。 DoWork需要在主GUI线程的单独线程上,因为主GUI线程需要自由地抽取消息队列(允许它重绘自己,处理不同的GUI事件等)尝试创建简单的GUI程序在主线程中有一段时间(真实)并且看到GUI卡住了并且没有自己重绘。

问题2.有人可以为我解释一下RefreshPresentation功能吗? (BeginInvoke和委托)

A2。虽然DoWork需要在另一个线程上完成,因此它不会阻止GUI线程,但更新GUI需要始终从GUI线程完成。为了实现这一点,您可以调用BeginInvoke,它将消息发布到消息队列并使您的委托在GUI线程上执行。

问题3.将MainForm作为参数传递给BusinessLogic是一个好主意/做法吗?

A3。不可以.MainForm可以了解业务逻辑,但业务逻辑不应该知道GUI。有关将GUI与业务逻辑分离的更多信息,请参阅Google“MVC”。

答案 1 :(得分:1)

1)看起来BusinessLogic做了一些冗长的工作。为了在此处理期间保持UI响应,它将在不同的线程中执行。

2)RefreshPresentation()是一个负责更新/刷新UI的方法,而后台线程正在处理以保持UI最新。由于UI不能从UI线程本身以外的线程更改,因此需要使用Invoke() / BeginInvoke()方法来分派要在UI线程上执行的代码。

3)我个人认为这是一个坏主意,而BusinessLogic类应该公开一个事件来通知数据更改。