2014-09-11 46 views
1

我正在開發WPF應用程序。 我有一些異步工作的定時器,它們是用System.Threading.Timer對象創建的。在C#WPF應用程序中異步調用與控件的委託方法

new System.Threading.Timer(
        new System.Threading.TimerCallback(Timer_Function), 
        null, 
        timing, 
        timing 
       ); 

Timer_Function() 
{ 
    /*code that runs asynchronously */ 
} 

爲了更新是在WPF查看我使用的委託方法被稱爲Dispatcher.Invoke否則編譯器將提高InvalidOperationException異常的控制(因爲不同的線程擁有它調用線程不能訪問該對象。)

我的問題是委託方法不會異步運行,我必須在其中做很多工作,以便應用程序停止。

我該怎麼做才能異步運行委託方法?

+1

Dispatcher.BeginInvoke – 2014-09-11 13:29:19

+0

感謝您的快速回復:-)。已經嘗試過,但仍然無法正常工作。 – user3492925 2014-09-11 14:19:23

+0

Timer_Function中的代碼是否真的沒有運行異步? 「做了很多工作」的部分在哪裏? – FishySwede 2014-09-11 14:50:39

回答

0

你需要做的是獨立出來的業務邏輯從顯示這些計算結果的代碼確定要顯示的內容。業務邏輯,非UI代碼應該在非UI線程中運行並計算出一些結果。那麼應該給這個結果一個方法,將編組到UI線程,然後顯示這些結果。

+0

是的。最後,我最終重新寫了一個像你所建議的解決方案。我將代碼中的所有代碼放在Timer_Function(由線程運行的方法)中,並且我爲每個單一操作獲取/更新一個UI組件。這不是一個非常可讀和舒適的解決方案(我會首選使用只是一個代表),但是...它無論如何工作。 – user3492925 2014-09-12 08:17:41

0

如果您需要程序在Timer_Function()代碼運行時繼續執行,則可以使用Task.Run在工作線程上執行該工作。

與平行執行一樣,您需要注意同步問題。確保在處理和分派工作之前不需要結果。正如你所說的那樣使用調度器可能就足夠了,只要確保你認真思考。

喜歡的東西:

Timer_Function() 
{ 
    Task.Run(() => 
    { 
      /* do your work here */ 
    }); 
} 

很抱歉,如果我誤解你的問題

+0

他不需要代碼就可以將工作移動到非UI線程。他*在非UI線程中啓動*。 – Servy 2014-09-11 15:30:04

0

對於異步任務,使用此 -

Task.Factory.StartNew(() => 
{ 
    // Code which needs to run asynchronously 
}.ContinueWith(task => 
    { 
     Application.Current.Dispatcher.Invoke(new Action(() => 
     { 
      // Code in which you are updating UI 
     }); 
    } 
+0

他不需要代碼就可以將工作移動到非UI線程。他*在非UI線程中啓動*。 – Servy 2014-09-11 15:31:37