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. メイン GUI スレッドはメッセージ キューをポンピングできるようにする必要があるため (これにより、それ自体を再描画したり、さまざまな GUI イベントを処理したりできるようになります)、単純な GUI プログラムを作成してみてください。メイン スレッドに while(true) があり、GUI がスタックして再描画されないことを確認します。

Q2.RefreshPresentation機能について説明してもらえますか? (BeginInvoke とデリゲート)

A2. DoWork は GUI スレッドをブロックしないように別のスレッドで実行する必要がありますが、GUI の更新は常に GUI スレッドから実行する必要があります。これを実現するために、BeginInvoke を呼び出すことができます。これにより、メッセージがメッセージ キューに投稿され、デリゲートが GUI スレッドで実行されます。

Q3. MainForm をパラメーターとして BusinessLogic に渡すのは良い考え/実践ですか?

A3. いいえ。MainForm はビジネス ロジックを認識できますが、ビジネス ロジックは GUI を認識する必要はありません。GUI をビジネス ロジックから分離する方法の詳細については、Google の「MVC」を参照してください。

于 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 に答える