0

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

  1. 为什么 businessLogic.DoWork 作为线程而不是普通的方法调用运行?
  2. 有人可以为我解释一下 RefreshPresentation 功能吗?(BeginInvoke 和委托)
  3. 将 MainForm 作为参数传递给 BusinessLogic 是一个好主意/做法吗?

这是应用程序的主要入口点。

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);
            }
        }

    }
4

2 回答 2

2

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

A1。DoWork 需要在一个单独的线程上,然后是主 GUI 线程,因为主 GUI 线程需要自由地泵送消息队列(这允许它重新绘制自己,处理不同的 GUI 事件等)尝试创建简单的 GUI 程序在主线程中有一段时间(true),并看到 GUI 卡住并且不会重绘自身。

Q2.谁能给我解释一下 RefreshPresentation 功能?(BeginInvoke 和委托)

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

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

A3。不。 MainForm 可以知道业务逻辑,但业务逻辑不应该知道 GUI。谷歌“MVC”以获取更多关于将 GUI 与业务逻辑分离的信息。

于 2010-12-02T12:29:12.203 回答
1

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

2)RefreshPresentation()是一种负责在后台线程处理时更新/刷新 UI 以使 UI 保持最新的方法。由于除了 UI 线程本身之外,无法从线程更改 UI,因此您需要使用Invoke()/BeginInvoke()方法来调度该代码以在 UI 线程上执行。

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

于 2010-12-02T12:30:13.003 回答