我想了解一些代码。这是一个打印日志数据的小程序。它是通过创建一个由DataTable填充的DataGridView的表单来完成的。表单类还具有刷新功能(RefreshPresentation)。 BusinessLogic类执行更新DataTable并在表单中调用refresh函数的实际工作。所以我非常了解功能,但不是为什么程序的结构是这样的。
这是该应用程序的主要入口点。
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);
}
}
}
答案 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
类应该公开一个事件来通知数据更改。