Asynchronous 将异步函数的完成链接到另一个函数
我正在开发一个Windows应用商店(C++)应用程序。这是一种使用web服务从数据库读取数据的方法Asynchronous 将异步函数的完成链接到另一个函数,asynchronous,windows-8,windows-store-apps,c++-cx,ppl,Asynchronous,Windows 8,Windows Store Apps,C++ Cx,Ppl,我正在开发一个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::F
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的完成链接到其他代码。以及如何从GetFromDB()的try{}块中获取返回值。请记住,我是异步编程的新手。如果对
GetFromDB
的调用继续发生在UI线程上(我相信默认情况下会发生,假设粘贴的调用站点发生在UI线程中),则调用get()在返回的任务上
将引发异常。它不会让您阻塞等待任务完成的UI线程
两个建议,其中任何一个都可以解决这个问题。不管怎样,第一个应该可以工作,而第二个是唯一一个好的选择,如果您不尝试将响应字符串获取到UI线程(例如,要显示)
1) 写下你的续集(你传递给然后
)这样他们就会得到上一个任务的实际结果,而不是上一个任务本身。换言之,与其这样写,不如这样写:
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... });
与后者不同的是,延续机制将为您(在后台线程上)调用get()
,然后将结果提供给延续函数,这在所有方面都要容易得多。如果要捕获任务执行时可能引发的异常,只需让continuation将实际任务作为参数
2) 告诉它在后台/任意线程上运行继续:
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }, task_continuation_context::use_arbitrary());
ternet.GetFromDB(…)。然后([this](任务响应){…},任务继续上下文::使用任意();
它不关心你是否阻止了后台线程,它只关心你是否在UI线程上调用了get()
。同样,实际的异常错误代码会很有用。你可以在中包装.get()调用,尝试{/*…*/}catch(Platform::exception^e){Platform::String^s=e->Message;}
然后设置一个断点并检查“s”获取有关异常的其他信息。
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... });
ternet.GetFromDB(...).then([this](std::wstring response) { ... });
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }, task_continuation_context::use_arbitrary());