2012-04-02 6 views
0

私のSilverlightアプリケーションでは、実行を続ける前に複数のオブジェクトがロードを完了するのを待つ必要があります。私が使用ManualResetEventをこのように試してみました:私はObjectLoadedがトリガをbeeingていませんManualResetEvent使用するときにアプリケーションがWAITONEで立ち往生のようSilverlight複数のオブジェクトがロードされたイベントをトリガーするのを待つ

ManualResetEvent _waitHandle = new ManualResetEvent(false); 
int objectsToLoad = 0; 
int objectsLoaded = 0; 

private void MethodA() 
{ 
    // do stuff 

    // count number of objects to Load and set objectsToLoad  
    objectsToLoad = x; 

    // change multiple objects interface which should trigger ObjectLoaded 

    // wait for all objects trigger loaded event 
    _waitHandle.WaitOne(); 
    _waitHandle.Reset(); 
} 

private void ObjectLoaded(object sender, RoutedEventArgs e) 
{ 
    objectsLoaded ++; 
    if (objectsToLoad == objectsLoaded) 
    { 
     objectsToLoad = 0; 
     objectsLoaded = 0; 
     _waitHandle.Set(); 
    } 
} 

しかし、それはそうです。

私は間違ったアプローチを使用していますか?この問題をどのように解決すればよいですか?

答えて

2

あなたが気付いたように、ManualResetEventを使用しないでください。メッセージポンプ(GUI)が処理されず、あなたが待っている他のものが必要になることはありません。メッセージポンプをアクティブにする。 整数を使用し、終了したイベントごとに整数を増やし、各イベントにコードを入れて、値が探しているカウントであるかどうかを確認します。または、別のboolを使用して、各イベントですべてが真であるかどうかを確認します。

+0

問題は、私が "_waitHandle.WaitOne();"を置いた場所から実行を続ける必要があるということです。残念なことに、すべてのイベントがObjectLoadedメソッドにロードされる時期を知ることはあまり役に立ちません。 – Canastro

+0

残念ながら、関数が完了しないようにするものは、WPFの処理を停止します。私が知る限り、この制限を回避する方法はありません。 –

0

ここで最初の答えにあなたのコメントを読んだら、それほどエレガントでないアプローチは、フォーマットがwhile(objectsToLoad != objectsLoaded)であるwhileループを持つことです。 whileループの中では、whileループ状態を解消しないように、数百ミリ秒の間スレッドスリープのようなものを置いてください。これにより、MethodAは次の実行ポイントを維持することができますが、Loadedイベントハンドラは最終的にwhileループの条件をtrueにします。

int objectsToLoad = 0; 
int objectsLoaded = 0; 

private void MethodA() 
{ 
    // do stuff 

    // count number of objects to Load and set objectsToLoad  
    objectsToLoad = x; 

    // change multiple objects interface which should trigger ObjectLoaded 

    // wait for all objects trigger loaded event 
    while(objectsToLoad != objectsLoaded) 
    { 
     System.Threading.Thread.Sleep(500); 
    } 
} 

private void ObjectLoaded(object sender, RoutedEventArgs e) 
{ 
    objectsLoaded ++; 
} 
+0

これは試しましたか?私は、睡眠はメッセージをポンピングしないので、単純に睡眠は問題を解決しないことが恐れています。 –

+0

私はこの特定のシナリオでそれを試していませんでした。私は以前にも同様の構成を使用して成功しました。より洗練されたことは、ObjectLoadedハンドラから「すべてが完了しました」イベントを処理するデリゲート/ハンドラをカウントマッチングを満たす場合に作成することです。 MethodAのコンテキストが必要な場合は、次の2つのことができます。1)すべてのコントロールがMethodAの外に移動してロードする必要があるロジックをリファクタリングする。 2)クラスレベルでアクションを定義し、MethodA内のラムダとして定義し、MethodA内の変数へのクロージャを与えます。 – avanek

関連する問題