2011-12-21 9 views
3

私は、アプリケーションのデータベースが増加するにつれて、結果を返すのにかかる時間も増加していることに気付きました。最初は、データソースを返す時間がそれほど短かったため、これはごくわずかでした。バックグラウンドワーカーにとって共通の方法はありますか?

私は一時的にUIを数秒間応答しないようにしていますが、これらのタスクを実行するにはbackground workersを作成したいと思います。

これらを作成する際の問題は、バックグラウンドワーカーが必要な約9つのボタンがあり、DLL内で異なるメソッドを呼び出すことです。バックグラウンドワーカー向けのAPIを使用してこれらのバックグラウンドワーカーを作成するための共通の方法を使用する方法はありますか、または各ボタンに対応するEnumを作成して、バックグラウンドワーカーを構築するメソッドによって取り込まれるパラメータです。つまり、単純なswitchを使用して、私が選んだDLLのどのメソッドを実行することができますか?

サンプルコード:

void bg_DoWorkImports(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 

     try 
     { 
      e.Result = EngineBllUtility.GetNotImportedFiles(connectionString); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

    void bg_RunWorkerCompletedImports(object sender, RunWorkerCompletedEventArgs e) 
    { 
     DataSet temp = (DataSet)e.Result; 
     if (e.Result != null) 
     { 
      importFileGridView.DataSource = temp.Tables[0]; 
     } 
    } 
+0

.NET 4を使用していますか? TPLは、このタイプのシナリオでBackgroundWorkerに代わる素晴らしい方法です... –

+0

残念なことに.NET 3.5 – ediblecode

+0

TPLを取得するので、Rxフレームワークへの依存はオプションになりますか? http://msdn.microsoft.com/en-us/data/gg577610 –

答えて

2

Func<T>を、BackgroundWorkerを作成し、内部からDoWorkイベントに呼び出すメソッドに渡すことができます。

代わりにBackgroundWorkerの、TPLを使用することです代替を使用して、この

public class BackgroundWrapper<T> 
{ 
    private Func<T> workMethod; 
    private Action<T> completeMethod; 
    public static void StartBackgroundworker(Func<T> workMethod, Action<T> completeMethod) 
    { 
     BackgroundWrapper<T> bWrap = new BackgroundWrapper<T>(); 
     bWrap.workMethod = workMethod; 
     bWrap.completeMethod = completeMethod; 
     bWrap.Start(); 
    } 

    private void Start() 
    { 
     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     bw.RunWorkerAsync(); 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     completeMethod((T)e.Result); 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     e.Result = workMethod(); 
    } 
} 
+0

Albinありがとう、私はこの方法を探検します。 – ediblecode

+2

あなたは本質的に 'System.Threading.Tasks'名前空間の機能を再現しました。ジョブには適切なツールを使用します。 'BackgroundWorker'はここでは適切なツールではないかもしれません。 –

+1

@AdamRobinsonそれは基本的に私の考えでした。もしあなたがこれを通過しようとするなら、あなたはTPLを使うことができます.TPLは、とにかく多くの点でより良いです... –

0

私はあなたが1人の背景労働者がボタンクリックジョブのそれぞれをピックアップし、次々にキックオフキューイングメカニズムのいくつかの種類を構築する必要があると思います。

+0

クマール、これは望ましくない機能になるでしょう – ediblecode

1

確かに、なぜあなたはそれのために「スイッチボード」の種類の機能を作成できなかったのか分かりません。実際には、これをやりたいかもしれません。なぜなら、モジュール化を少し進め、コードの再利用を促進するからです。

enumsが個人的に行っている限り、私は、そのようなものの中から多くの引数を渡すためのクラスを作成します。

2

ような何か。これにより、各メンバーに直接コードを書くことができます。

void buttonImport_Click(object sender, DoWorkEventArgs e) 
{ 
    Task.Factory 
     .StartNew(() => return EngineBllUtility.GetNotImportedFiles(connectionString)) 
     .ContinueWith(t => 
    {   
     try 
     { 
      if (t.Result != null) 
      { 
       importFileGridView.DataSource = t.Result.Tables[0]; 
      } 
     } 
     catch (AggregateException ex) 
     { 
      MessageBox.Show(ex.InnerException.Message); 
     } 
    }, TaskScheduler.FromCurrentSynchronizationContext()); 
} 
関連する問題