Q:

Trying to understand a logreader

I am trying to understand some code.  It is a small program that prints out log data.  It is done by creating a form with a DataGridView that is filled by a DataTable.  The form class also has a refresh function (RefreshPresentation).  The BusinessLogic class does the actual work of updating the DataTable and calling the refresh function in the form.  So I pretty much understand the functionality, but not why the program is structured the way it is. 

Why is businessLogic. DoWork run as a
thread instead of just a normal method call? 
Can someone explain the
RefreshPresentation function for me? 
(BeginInvoke and the delegate)
Is it a good idea/practice to pass the MainForm as a parameter to BusinessLogic? 

This is the main entry point for the application. 
public class Program
    {
        [STAThread]
        static void Main()
        {
            Application. EnableVisualStyles();
            Application. SetCompatibleTextRenderingDefault(false);
            Application. Run(new MainForm());            
        }
    }

This is the relevant part of the form. 
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;
        }
...

This is the business logic. 
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);
            }
        }

    }

A:

Q1.Why is businessLogic. DoWork run as a thread instead of just a normal method call?  
A1.  DoWork needs to be on a separate thread then the main GUI thread, since the main GUI thread needs to be free to pump the message queue (which allows it to redraw itself, handle different GUI events, etc.)  Try to create simple GUI program that has a while(true) in the main thread and see that the GUI gets stuck and doesn't redraw itself. 
Q2.Can someone explain the RefreshPresentation function for me? ( BeginInvoke and the delegate)
A2.  Though the DoWork needs to be done on another thread so it doesn't block the GUI thread, updating the GUI needs to always be done from a GUI thread.   In order to make this happen, you can call BeginInvoke, which posts a message to the message queue and causes your delegate to be executed on the GUI thread. 
Q3.Is it a good idea/practice to pass the MainForm as a parameter to BusinessLogic? 
A3.  No.  The MainForm can know about the business logic, but the business logic should not be aware of the GUI.   Google "MVC" for more information on separating the GUI from the business logic.