问题:当我想呈现异步检索的传入数据时,我崩溃了。Metro C++异步编程和UI更新。我的技术?
该应用程序启动并使用XAML显示一些对话框。一旦用户填写了他们的数据并点击了登录按钮,XAML类就拥有了一个为我执行HTTP内容的工作类实例(异步使用IXMLHTTPRequest2)。当应用程序成功登录到Web服务器时,我的.then()块会触发,并且会对我的主要xaml类进行回调以执行资源渲染。
尽管(主XAML类)我总是在代理中发生崩溃,这导致我相信我不能使用这种方法(纯虚类和回调函数)来更新我的UI。我认为我无意中尝试从异步调用的副产品不正确的线程中进行非法操作。
有没有更好或不同的方式,我应该通知主XAML类,它是时候更新它的UI了?我来自iOS世界,我可以使用NotificationCenter。
现在,我看到了微软的东西在这里它自己的委托类型:http://msdn.microsoft.com/en-us/library/windows/apps/hh755798.aspx
你想,如果我用这种方法不是我自己的回调,这将不再崩溃?
让我知道你是否需要更多的澄清或不。
这里是代码的JIST: 公共接口类ISmileServiceEvents { 公共://所需的方法 虚拟无效UpdateUI(布尔的isValid)抽象; };
// In main XAML.cpp which inherits from an ISmileServiceEvents
void buttonClick(...){
_myUser->LoginAndGetAssets(txtEmail->Text, txtPass->Password);
}
void UpdateUI(String^ data) // implements ISmileServiceEvents
{
// This is where I would render my assets if I could.
// Cannot legally do much here. Always crashes.
// Follow the rest of the code to get here.
}
// In MyUser.cpp
void LoginAndGetAssets(String^ email, String^ password){
Uri^ uri = ref new URI(MY_SERVER + "login.json");
String^ inJSON = "some json input data here"; // serialized email and password with other data
// make the HTTP request to login, then notify XAML that it has data to render.
_myService->HTTPPostAsync(uri, json).then([](String^ outputJson){
String^ assets = MyParser::Parse(outputJSON);
// The Login has returned and we have our json output data
if(_delegate)
{
_delegate->UpdateUI(assets);
}
});
}
// In MyService.cpp
task<String^> MyService::HTTPPostAsync(Uri^ uri, String^ json)
{
return _httpRequest.PostAsync(uri,
json->Data(),
_cancellationTokenSource.get_token()).then([this](task<std::wstring> response)
{
try
{
if(_httpRequest.GetStatusCode() != 200) SM_LOG_WARNING("Status code=", _httpRequest.GetStatusCode());
String^ j = ref new String(response.get().c_str());
return j;
}
catch (Exception^ ex) .......;
return ref new String(L"");
}, task_continuation_context::use_current());
}
编辑:BTW,当我去更新UI我得到的错误是: “一个无效参数传递给确认为无效参数致命的函数” 在这种情况下,我只是想在我的回调执行是
txtBox->Text = data;
感谢您的链接。我读完了,说什么与你的建议相矛盾。从文章: “ 使用并发:: task_continuation_context :: use_arbitrary指定延续在后台线程运行 使用并发:: task_continuation_context :: use_current指定延续调用任务的线程上运行: :然后 “ – VaporwareWolf
无论哪种方式,我试图改变任意()和删除use_current()。两人都没有帮助解决问题。 – VaporwareWolf