2012-12-30 128 views
4

我正在開發一個庫,它提供了一些耗時的服務。我需要每個API有兩個版本,一個用於同步函數調用,另一個用於異步。同步和異步API

圖書館用戶應該決定使用哪個版本,服務結果對於繼續系統操作(同步呼叫)可能至關重要。可能需要在不同的工作線程中完成相同的操作,因爲它不需要繼續(異步調用)。

這種方法有什麼問題?

有沒有更好的辦法?

是否有流行的庫爲相同的API提供同步/異步(不使用外部事件或線程)?

這裏是什麼,我要提供的一個例子:

enum StuffStatus 
{ 
    SUCCEED, 
    FAILED, 
    STILL_RUNNING 
}; 
class IServiceCallback 
{ 
public: 
    void lengthyStuffCallback(StuffStatus status); 
}; 

class MyServiceClass 
{ 
public: 
    StuffStatus doSomeLengthStuff(IServiceCallback* callback) 
    { 
     if(callback == NULL) // user wants sync. call 
     { 
      // do all operations in caller context 
      return SUCCEED; 
     }else{ 
      // save the callback, queue the request in a separate worker thread. 
      // and after the worker thread finishes the job it calls callback->lengthyStuffCallback(SUCCEED) from its context. 
      return STILL_RUNNING; 
     } 
    } 
}; 

編輯: 作爲 '馬修M.'在我的服務中,我需要使用Continuation Passing Style(API完成後的回調)進行異步處理。

+1

注意:異步操作並不意味着延續傳遞樣式(以及使用回調函數)。請記住,經常傳遞迴調無法讓代碼變得不可讀。 –

+0

Boost.Asio同時具有異步API的CPS。我認爲它工作得很好,你可能想看看它。作爲'Matthieu M'表示的 – Xeo

回答

5

你可能要考慮到提供同步運行,並建議用戶使用std::future<...>(或類似的設施,如果您不能使用C++ 2011),如果他們想呼叫的異步版本!

std::future<StuffStatus> async(std::async(&MyServiceClass::doSomeLengthyStuff, 
              &service)); 
// do other stuff 
StuffStatus status = async.get(); // get the result, possibly using a blocking wait 
+0

,std :: async不提供延續傳遞樣式。我想讓該方法運行異步並在完成後調用回調。 – Yousf