2013-04-03 28 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()

相关问题