2013-04-03 27 views
0

我正在使用Windows應用商店(C++)應用程序。這是一種使用Web服務從數據庫中讀取數據的方法。將異步函數的完成鏈連接到另一個

task<std::wstring> Ternet::GetFromDB(cancellation_token cancellationToken) 
{ 
    uriString = ref new String(L"http://myHost:1234/RestServiceImpl.svc/attempt"); 
    auto uri = ref new Windows::Foundation::Uri(Helpers::Trim(uriString)); 
    cancellationTokenSource = cancellation_token_source(); 
    return httpRequest.GetAsync(uri, cancellationTokenSource.get_token()).then([this](task<std::wstring> response)->std::wstring 
    { 
     try 
     { 
      Windows::UI::Popups::MessageDialog wMsg(ref new String(response.get().c_str()), "success"); 
      wMsg.ShowAsync(); 
      return response.get(); 
     } 
     catch (const task_canceled&) 
     { 
      Windows::UI::Popups::MessageDialog wMsg("Couldn't load content. Check internet connectivity.", "Error"); 
      wMsg.ShowAsync(); 
      std::wstring abc; 
      return abc; 
     } 
     catch (Exception^ ex) 
     { 
      Windows::UI::Popups::MessageDialog wMsg("Couldn't load content. Check internet connectivity.", "Error"); 
      wMsg.ShowAsync(); 
      std::wstring abc; 
      return abc; 
     } 
    } , task_continuation_context::use_current()); 
} 

我很困惑如何將接收到的數據返回給調用函數。每當我試圖從GetFromDB接收返回的數據()

ternet.GetFromDB(cancellationTokenSource.get_token()).then([this](task<std::wstring> response) 
{ 
    data = ref new String(response.get().c_str()); 
}); 

我得到一個COM異常:現在,我在我的數據類的這樣的構造調用這個函數。但是,這在一個晴朗的運行:

ternet.GetFromDB(cancellationTokenSource.get_token()); 

請建議鏈接GetFromDB完成對其他代碼的一種更好的方式。然後如何從GetFromDB()的try {}塊中獲取返回的值。請記住,我是一名非常新的異步編程學生。

+0

同樣,實際的異常錯誤代碼會有幫助。 – 2013-04-04 12:26:39

+0

您可以將.get()調用包裝在try {/*...*/} catch(Platform :: Exception^e)Platform :: String^s = e-> Message中; }'然後設置一個斷點並檢查「s」以獲取有關異常的其他信息。 – 2013-04-11 22:39:07

回答

0

如果調用GetFromDB的繼續發生在UI線程(我相信它會在默認情況下,假設你粘貼在UI線程正在發生調用點),然後調用返回的taskget()將拋出一個例外。它不會讓你阻止等待任務完成的UI線程。

兩個建議,其中任何一個都應該解決這個問題。第一個應該工作不管,而第二個只是一個不錯的選擇,如果你沒有嘗試獲取UI線程的響應字符串(例如顯示)。 1)編寫你的延續(你傳遞給then的lambda),以便它們取得前一個任務的實際結果,而不是前一個任務本身。換句話說,而不是寫這個:

ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }); 

這樣寫:

ternet.GetFromDB(...).then([this](std::wstring response) { ... }); 

與後者不同的是,延續機械將調用get()你(在後臺線程),然後給你的延續功能的結果,這是很容易四處。如果您想要捕獲任務在執行時可能拋出的異常,只需要讓您的延續將實際任務作爲參數。

2)告訴它在後臺/任意線程運行延續:

ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }, task_continuation_context::use_arbitrary()); 

如果您阻止後臺線程它不會在意,只在乎你是否在UI線程調用get()

相關問題