2010-02-28 96 views
3

與異步委託一起使用的模式也是一種回調模式,其中初始線程(稱爲BeginInvoke的一個)T1繼續而不等待或檢查衍生線程T2是否已完成。相反,當T2完成時,T2調用處理結果的回調方法,調用EndInvoke並通知T1任務完成。什麼時候異步委託使用回調模式?

a)如果回調方法應該在任務完成時通知T1,那麼爲什麼不是在T1內部調用這個回調方法,而不是T2?

2)是否有一些標準模式回調方法應該告訴T1 T2已經完成?

3)是否應該使用回調模式,即使T1需要接收異步調用方法的返回值?

感謝名單

+0

T1爲什麼要對T2中發生了什麼事情進行廢話?線程不是什麼,而是執行上下文; T1對T1中發生的事情無關緊要。重要的是,應用程序進入後,只有當它進入狀態X時Y纔會發生。爲什麼Y必須由T1完成(除UI異常外)? – Will 2010-02-28 20:12:14

回答

3
  • 爲什麼被稱爲在T1不回調方法?

通常這是不可能的;如果T1關閉了一些其他工作,除非線程已經有一個發佈和調度工作的機制(例如通過SynchronizationContext的UI線程),否則無法將工作重新組織到工作中。

  • 是否存在跨線程通知的標準模式?

我會說不;有許多跨線程同步模式,每種模式都適用於不同的目標場景。

  • 如果T1需要返回值,該怎麼辦?

如果T1需要當前棧下的返回值,那麼最終它將不得不阻止獲取它。阻塞可能通過調用EndInvoke,使用WaitHandle或上一個項目符號中的其他策略來實現。

如果需要返回值的東西是'只是線程'(例如UI線程)而不是在特定的callstack /激活環境下,那麼通常會使用SynchronizationContext.Post或Dispatcher.Invoke來最終編組工作一旦準備好就返回到UI線程。

+0

我假設如果T2需要通知T1它已經完成,那麼實現回調方法(即回調模式)與輪詢模式(其中T1通過IsCompleted屬性定期檢查生成的線程是否已完成)沒有任何優點,因此我們應該改爲實現輪詢模式? – AspOnMyNet 2010-02-28 20:38:18

3

讓線程在另一個線程中運行代碼是非常平凡的。但這是Windows窗體和WPF應用程序的常見要求,用戶界面組件永遠不會線程安全。他們有一個共同的模式,分別Control.Invoke和Dispatcher.Invoke方法。還有一個標準的助手類,BackgroundWorker。它在UI線程上引發事件,它的模擬回調方法是它的RunWorkerCompleted事件。

如果您更喜歡使用委託的BeginInvoke()方法,那麼您肯定可以旋轉自己的機制,但獲得該權利可能會非常棘手。