2013年5月8日 星期三

[W8App] Make Native Runtime Component (2): Delegate and Event

除了async / await等待非同步的RunTime Component完成工作外,Native Runtime Component能否透過callback (或 message)來取得運算更新?W8App已不再用傳統的callback / message loop來進行元件之間的溝通,取而代之的是delegate / event機制,我們必需做三件事使呼叫端能得知元件的事件觸發。

1. 元件必需提供delegate handler:
#1 delegate的宣告必需在class的宣告之前
#9 class中必需有delegate hander event,讓元件可發送事件,呼叫端可聆聽事件
#5 class中必需有dispatcher用來記錄呼叫端執行緒的dispatcher

   1: public delegate void ProcessedHandler(int retry);
   2: public ref class myTRDLL sealed
   3: {
   4: private:
   5:   Windows::UI::Core::CoreDispatcher^ m_dispatcher;
   6:  
   7:   // DO SOMETHING
   8: public:
   9:   event ProcessedHandler^ ProcessedEvent;
  10: };

2. 呼叫端(C# app)必需 += 聆聽這個事件



   1: _myRTDLL.ProcessedEvent += OnRTDLLProcessedEvent;

3. 元件觸發事件
#4 在產生非同步的task前記錄呼叫端AP執行緒的dispatcher
#16 觸發ProcessedEvent事件
#14 確保AP是在main thread接收到event。如果忘了做這個動作,會收到0x8001010E的例外事件。



   1: IAsyncOperation<int>^ myRTDLL::RunProcessAsync(int maxretry)
   2: {
   3:   auto window = Windows::UI::Core::CoreWindow::GetForCurrentThread();
   4:   m_dispatcher = window->Dispatcher;
   5:  
   6:   return create_async([this,maxretry]() {
   7:     int retry = 0;
   8:  
   9:     for( ; retry<maxretry ; retry++)
  10:     {
  11:       if(RunProcess(retry))  break;
  12:     }
  13:  
  14:     m_dispatcher->RunAsync( CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, retry]() 
  15:     {
  16:       this->ProcessedEvent(retry);
  17:     }, Platform::CallbackContext::Any));
  18:  
  19:     return (retry < maxretry) ? retry : -1;
  20:   });
  21: }

(當初沒做dispatch這個動作花了好多時間debug…)

沒有留言:

張貼留言