我正在开发一个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());
}
我很困惑如何将收到的数据返回给调用函数。现在,我在我的数据类的构造函数中调用此函数,如下所示:
ternet.GetFromDB(cancellationTokenSource.get_token()).then([this](task<std::wstring> response)
{
data = ref new String(response.get().c_str());
});
每当我尝试从GetFromDB()接收返回的数据时,我都会收到COM异常。但是这个运行得很好:
ternet.GetFromDB(cancellationTokenSource.get_token());
请建议将GetFromDB完成链接到其他代码的更好方法。以及如何从GetFromDB()的try {}块中获取返回值。请记住,我是异步编程的新生。
答案 0 :(得分:0)
如果在UI线程上发生对GetFromDB
的调用的继续(我相信默认情况下,假设您粘贴的调用站点正在UI线程中发生),则调用{{1}在返回的get()
上将抛出异常。它不会让你阻止等待任务完成的UI线程。
两个建议,其中任何一个都应该解决这个问题。第一个应该可以工作,而第二个只是一个很好的选择,如果你没有尝试获取UI线程的响应字符串(例如,显示)。
1)编写你的延续(传递给task
的lambda),使它们获取前一个任务的实际结果,而不是前一个任务本身。换句话说,而不是写这个:
then
写下这个:
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... });
与后者的不同之处在于,延续机制将为您调用ternet.GetFromDB(...).then([this](std::wstring response) { ... });
(在后台线程上),然后将结果提供给您的延续函数,这样可以更加轻松。如果要捕获任务在执行时可能抛出的异常,您只需要让您的继续将实际任务作为参数。
2)告诉它在后台/任意线程上运行你的继续:
get()
如果您阻止后台线程,则无关紧,只关注在UI线程上调用ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }, task_continuation_context::use_arbitrary());
。