2011-10-20 23 views
2

これは私のターゲットです。このアプリケーションは、フォーム(MainForm)にタブ(Notepad ++ GUIのようなもの)が多数含まれています。各タブは、UserControlの子孫(UCDx)です。 MainFormは、同じUCDxのインスタンスを含む2つ以上のタブを表示できます。目標は、UCDxが時間のかかる処理やメソッドの実行(DBの読み書き、Webサービスメソッドの呼び出しなど)を実行する必要があることです。この種のアクションは、UIをフリーズさせないために、別々のスレッドで実行したいと考えています。また、情報フォーム(InfoForm)を実装する必要があります。これは、現在実行中のスレッドに情報を表示し、いくつかの対話機能、つまりあまりにも長く実行されるスレッドを閉じます。私が直面.NET WinFormアプリケーションでスレッドを管理する

主な問題は、次のとおりGUIと

  • スレッド相互作用 - すなわち、スレッドは、グリッドに表示されるべきデータを読み出します。
  • スレッドインタラクション管理 - InfoFormの実装時。

私は初心者です - 誰かがそれを実装する方法の手がかりを与えることができますか?

答えて

4

私は最初にUIからワーカーロジックを分離します。

たとえば、「データを読み取り、それを表示する必要があるスレッド」のために、小さな断片にあなたの問題を分割しよう:

  1. は、同期処理の方法を持っている平野クラス、無スレッドを作成します。関与する。次のようなもの:

    interface IServiceReader 
    { 
        Data GetDataFromService(IServiceInfo info); 
    } 
    
  2. テストします。ユニットテストを作成するか、GUIなしで正常に動作することがわかる小さなコンソールアプリケーションを作成してください。

  3. ジョブを実行するためにServiceReaderを呼び出しますが、バックグラウンドスレッドで呼び出す非同期ラッパークラスを作成し、終了時にイベントを発生させます。

    interface IAsyncServiceReader 
    { 
        void Start(IServiceInfo info); 
        event EventHandler<Data> DataReceived; 
    } 
    
  4. もう一度テストします。これは、GUIとは独立した別個のクラスライブラリでなければなりません。

  5. MVCまたは類似のパターンを使用して、モデル(非同期サービスリーダー)からビュー(タブ)を分離します。これは、あなたが、あなたのビューからインタラクションイベントを発生さコントローラでそれらを処理した後、コントローラは、モデル内の適切なアクションを呼び出してみましょう必要があります意味:

    class Controller 
    { 
        readonly ITabView _view; 
        readonly IAsyncServiceReader _model; 
        public Controller(ITabView view, IAsyncServiceReader model) 
        { 
          _view = view; _model = model; 
          AttachHandlers(); 
        } 
    
        void AttachHandlers() 
        { 
          view.UserRequestedLoading += (sender,info) => model.Start(info); 
          model.DataReceived += (sender,data) => view.DisplayData(data); 
        } 
    } 
    
  6. 最後に、(バックグラウンドスレッドの呼び出しが右にディスパッチされていることを確認しますGUI)スレッド。テストを簡素化するビューからモデルを分離

    class TabView : UserControl 
    { 
        void DisplayData(Data data) 
        { 
         if (this.InvokeRequired) 
         { 
          BeginInvoke(new Action<Data>(DisplayData), data); 
          return; 
         } 
    
         // otherwise, display the data in some way 
         dataGrid.DataSource = data; ... 
        } 
    } 
    

、およびUIへの以降の変更:これは単にあなたのタブビューは呼び出しが必要になるかどうかを確認する必要がありますを意味します。これをコンソールアプリケーションまたはWindowsサービスにすることができます。これにより、ビジネスロジックが損なわれません。

+0

うん...いいスタート地点...ありがとう – DreadAngel

0

使用GUIでアクションを実行するためにバックグラウンドスレッドから呼び出します。マルチスレッドのソリューションには、タスク、バックグラウンドワーカー、カスタムスレッド、スレッドプールなどがあります。非同期操作も使用できます。

0

この問題に関する多くの情報を読んだら(最も重要なのはAlbahari threads docs)、ここに私の考えを実装するための最初の試みがある - gCodeからsvn経由で取る。 あなたは私たちの意見や意見が必要です。ありがとうございました。

関連する問題