2010-12-02 3 views
0

일부 코드를 이해하려고합니다. 로그 데이터를 출력하는 작은 프로그램입니다. DataTable으로 채워진 DataGridView로 양식을 작성하면됩니다. 양식 클래스에는 새로 고침 기능 (RefreshPresentation)도 있습니다. BusinessLogic 클래스는 DataTable을 업데이트하고 폼에서 새로 고침 함수를 호출하는 실제 작업을 수행합니다. 그래서 나는 그 기능을 꽤 많이 이해하지만, 왜 프로그램이 어떻게 구성되어 있는지를 이해하지 못합니다.logreader를 이해하려고 시도했습니다.

  1. 일반 메서드 호출 대신 businessLogic.DoWork가 스레드로 실행되는 이유는 무엇입니까?
  2. 나를 위해 RefreshPresentation 함수를 설명 할 수 있습니까? (BeginInvoke 및 대리자)
  3. MainLogic을 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); 
      } 
     } 

    } 

답변

2

질문 1. businessLogic.DoWork가 일반 메서드 호출 대신 스레드로 실행되는 이유는 무엇입니까?

a1. DoWork는 메인 GUI 스레드가 별도의 스레드에 있어야하며, 메인 GUI 스레드는 메시지 대기열을 펌프 할 필요가 있으므로 (자체 GUI를 다시 그리거나 다른 GUI 이벤트를 처리 할 수 ​​있음) 간단한 GUI 프로그램을 작성하십시오. 메인 스레드에서 잠시 동안 (true) GUI가 멈추고 다시 그리지 않는 것을 볼 수 있습니다.

Q2. 누군가 나를 위해 RefreshPresentation 기능을 설명 할 수 있습니까? (BeginInvoke 및 대표)

A2. GUI 스레드를 차단하지 않도록 DoWork를 다른 스레드에서 수행해야하지만 GUI 업데이트는 항상 GUI 스레드에서 수행해야합니다. 이 문제를 해결하기 위해 BeginInvoke를 호출하면 메시지 대기열에 메시지를 게시하고 GUI 스레드에서 대리인을 실행하게 할 수 있습니다.

Q3. MainForm을 BusinessLogic에 대한 매개 변수로 전달하는 것이 좋습니다.

A3. 아니요. MainForm은 비즈니스 로직을 알 수 있지만 비즈니스 로직은 GUI를 인식해서는 안됩니다. GUI를 비즈니스 논리에서 분리하는 방법에 대한 자세한 내용은 Google "MVC"를 참조하십시오.

+0

많은 도움이되었습니다. 고맙습니다. –

1

1) BusinessLogic은 다소 오랜 시간 일을하고있는 것 같습니다. 이 처리 중에 UI를 응답하게 유지하려면 다른 스레드에서 UI가 실행됩니다.

2) RefreshPresentation()은 백그라운드 스레드가 UI를 최신 상태로 유지하는 동안 UI를 업데이트/새로 고치는 방법입니다. UI 스레드 자체가 아닌 스레드에서 UI를 변경할 수 없기 때문에 Invoke()/BeginInvoke() 메서드를 사용하여 해당 코드를 UI 스레드에서 실행되도록 처리해야합니다.

3) 저는 개인적으로 나쁜 생각이고 대신 이벤트가 데이터 변경을 알리는 BusinessLogic 클래스에 의해 노출되어야한다고 생각합니다.

+0

그건 의미가 있습니다. 아니. 3 나쁜 생각으로 나를 때렸다 (형태를 통과). 어쩌면 이벤트 노출은 SpeksETC에서 제안한 MVC 솔루션의 일부일 수 있습니다. 나는 그것을 조사해야 할 것이다. 고맙습니다. –

관련 문제