2012-04-02 70 views
0

在我的silverlight應用程序中,我需要等待多個對象完成加載,才能繼續執行。我嘗試使用ManualResetEvent的是這樣的: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(); 
    } 
} 

當我使用的ManualResetEvent的ObjectLoaded不beeing觸發,好像應用卡上的WaitOne。

我使用了錯誤的方法嗎?我應該如何解決這個問題?

回答

2

不要使用ManualResetEvent的,因爲你已經注意到,它不會允許消息泵(圖形用戶界面)來處理,你永遠不會得到任何進一步的,你就等着其他的事情需要消息泵被激活。 只需使用一個整數併爲每個完成的事件增加它,然後將代碼放在每個事件上以檢查值是否是您要查找的計數。或者,使用單獨的bools並檢查每個事件是否都是真的。

+0

問題是我需要繼續執行從我推出「_waitHandle.WaitOne();」的地方。所以,不幸的是,知道何時在ObjectLoaded方法上加載所有事件並不是很有幫助。 – Canastro 2012-04-02 13:41:08

+0

不幸的是,任何阻止函數完成的東西都會阻止WPF進一步處理。據我所知,這個限制沒有任何辦法。 – 2012-04-02 17:08:40

0

在閱讀你對第一個答案的評論之後,一個不那麼優雅的方法是使用格式爲while(objectsToLoad != objectsLoaded)的while循環。在while循環中,像線程一樣睡幾百毫秒,這樣就不會掛住while循環條件。這允許MethodA維護下一個執行點,而Loaded事件處理程序最終使while循環的條件成立。

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

你有沒有試過這個?恐怕簡單的睡眠不會解決這個問題,因爲睡眠不會傳遞信息。 – 2012-04-02 17:09:40

+0

我沒有在這個特定的場景中嘗試過,沒有。我曾經使用過類似的構造,並取得了成功。更優雅的做法是創建一個委託/處理程序,如果它滿足計數匹配,則從ObjectLoaded處理程序處理「一切都已完成」事件。如果它需要MethodA的上下文,那麼你可以做兩件事:1)通過將所有控件加載到MethodA之外來重構需要發生的邏輯; 2)在類級定義一個動作並在MethodA中將其定義爲一個lambda,從而使您可以關閉MethodA中的變量。 – avanek 2012-04-02 18:32:32