2009-04-06 4 views
3

Windowsアプリケーションでは、定期的に操作を開始する必要がありますが、時間がかかることがあります。これらの操作をBackgroundWorker上で実行し、各操作のための簡単なWinFormを記述し、フォームに必要なパラメータを渡し、フォームがBackgroundWorkerを呼び出して関数呼び出しを行うパターンになっています。フォームには出力が表示されます(進行状況バーの移動、テキストの更新など)。.NETバックグラウンドワーカーの生成

明らかに、このフォームは非常にクッキーカッターです。フォームコピー間で実際に異なる部分は、どのメソッドがどのオブジェクトに対して呼び出されるかだけです。だから私たちがやりたいことは、フォームを取ったり、オブジェクト(静的呼び出しの場合はnull?)、関数名、およびパラメータの配列を渡し、そこから。我々はこれをReflectionで行うことができました。この場合の反射について私たちが好きでないことは、強タイピングの欠如です。メソッドコールのスペルミスのようなものは、実行時に捕捉され、コンパイル時ではありません。これをよりエレガントで強固にしてくれるものがありますか?私は、代表者や表情樹のようなものについて話している人について聞いたことがあります。私は前者が当てはまるとは思っていませんが、後者についてはまだ暗闇の中で少しです。

答えて

6

一般的なフォームを作成し、BackgroundWorkerで実行する必要があるメソッドを示すデリゲートを渡すと、分かりやすい解決策になります。

Formコンストラクタには、引数として汎用的なデリゲート(アクションが良い考えかもしれません)をとり、コンストラクタでActionのシグネチャと一致するラムダ式を渡すことができます。そして、foreachアクションでは、適切なラムダ式を指定するだけでよいでしょう。

ラムダ式はローカル変数を取り込むことができるので、前に行ったロジックを呼び出して同じパラメータを渡すことができることに注意してください。

+0

私が理解しているように、私は最終的にこのように呼び出されることになるかもしれない各メソッドのための新しいデリゲートを作成する必要がありますか? – GWLlosa

+0

@GWLIosa - 私はそれを明確にするために少し答えを広げようとしました。各メソッドに明示的なデリゲート型を指定する必要はありません。 – driis

3

ラムダ関数もチェックアウトすることができます。私はジェネリックスで働くときに特に使います。そうしないと、デリゲートはうまく動作します。あなたができる

2

ことの一つは、このようないくつかの異なる方法(引数なしのメソッドの1等1つの引数を持つメソッドに1つ)を作成されています。そして、

public static void DisplayForm(Action action) { 
    DisplayFormUsingInvoke(action); 
} 

public static void DisplayForm<T>(Action<T> action, T param) { 
    DisplayFormUsingInvoke(action, param); 
} 

public static void DisplayForm<T,U>(Action<T,U> action, T param1, U param2) { 
    DisplayFormUsingInvoke(action, param1, param2); 
} 

... 

を、あなたはプライベートメソッドを持つことができますこれは実際にあなたの現在の方法と同様に、作業を行いますが、クライアントコードにさらされていない:

private static void DisplayFormUsingInvoke(Delegate d, params object[] parms) { 
    // Edit this code to run it on the background thread, report progress, etc. 
    d.DynamicInvoke(parms); 
} 

そして、クライアントコードは、右引数の数と種類がある要件を適用しますpublicメソッドのいずれかを呼び出します。供給される。

関連する問題