2011-01-10 13 views
0

大量のデータを処理してUIを更新しようとしている次のコードがあります。バックグラウンドワーカーを使用して同じことを試しましたが、同様の問題が発生します。問題は、新しいスレッドでインスタンス化されていないクラスを使用しようとしているようです(実際のエラーは、現在のスレッドがインスタンスを所有していないということです)。私の質問は、このエラーを回避するためにスレッド間でこのインスタンスを渡すことができる方法はありますか?スレッド間でデータを渡す

DataInterfaceClass dataInterfaceClass = new DataInterfaceClass(); 

private void OutputData(List<MyResult> Data) 
{    
    progressBar1.Maximum = Data.Count; 
    progressBar1.Minimum = 1; 
    progressBar1.Value = 1; 

    foreach (MyResult res in Data) 
    {      
     // Add data to listview 
     UpdateStatus("Processing", res.Name); 

     foreach (KeyValuePair<int, string> dets in res.Details) 
     { 
      ThreadPool.QueueUserWorkItem((o) => 
      { 
       // Get large amount of data from DB based on key 
       // – gives error because DataInterfaceClass was 
       // created in different thread. 
       MyResult tmpResult = dataInterfaceClass 
        .GetInfo(dets.DataKey); 

       if (tmpResult == null) 
       { 
        // Updates listview 
        UpdateStatus("Could not get details", 
         dets.DataKey); 
       } 
       else 
       { 
        UpdateStatus("Got Details", dets.DataKey); 
       } 

       progressBar1.Dispatcher.BeginInvoke(
        (Action)(() => progressBar1.Value++)); 
      }); 
     } 
    } 
} 

EDIT:

DataInterfaceClassが実際definated、それが中に使用される関数の外部で作成、それはインスタンスと静的ではありません。

答えて

1

UPDATE: あなたはそれぞれのバックグラウンドスレッドやタスク専用DataInterfaceClassのインスタンスを作成する必要があります掲載のソースコードを変更しているように見えるので、...

。独自のインスタンスを作成するのに十分な入力をタスクに与えます。

つまり、単一のデータベースのデータに高度に並列的にアクセスしようとすると、データベースのタイムアウトが発生する可能性があります。マルチスレッドの方法でデータアクセスを行うことができたとしても、これが発生しないように同時にバックグラウンドタスクの数を制限することをお勧めします。

Semaphore(またはそれに類するもの)を使用すると、特定の量以上のタスクが同時に実行されないようにすることができます。

+0

DataInterfaceClassが静的であるように見えるので、質問を更新しました。同時タスクの数は、実行するUIのプロセスを更新するだけです(データの同時アクセスは想定していません)。 –

+0

@ pm_2:同時にアクセスする必要がない場合は、ネストされたループ内の作業項目をキューに入れるのではなく、両方の 'foreach'ループを単一の作業項目に入れる必要があります。 – Thorarin

0

メソッド内で使用できるように、OutputDataメソッドが定義されたクラス内にDataInterfaceClassのグローバルインスタンスを作成します。

ただし、使用には注意が必要です。すべてのスレッドが同じインスタンスを使用してデータベースから読み取ると、エラーが発生します。

DataInterfaceClassの新しいインスタンスを各スレッドに作成するか、複数のアクセスの問題を避けるためにGetInfoメソッド内でロックを実装する必要があります。

関連する問題