문제 : 비동기 적으로 검색된 수신 데이터를 렌더링하려고 할 때 충돌이 발생합니다.Metro C++ 비동기 프로그래밍 및 UI 업데이트. 내 기술?
앱이 시작되고 XAML을 사용하여 일부 대화 상자가 표시됩니다. 사용자가 데이터를 채우고 로그인 버튼을 클릭하면 XAML 클래스는 HTTP 항목을 (IXMLHTTPRequest2를 사용하여 비동기 적으로) 수행하는 작업자 클래스의 인스턴스에 있습니다. 응용 프로그램이 웹 서버에 성공적으로 로그인하면 .then() 블록이 실행되고 기본 xaml 클래스에 대한 콜백을 만들어 일부 자산 렌더링을 수행합니다.
비록 내가이 접근법 (순수 가상 클래스와 콜백)을 사용하여 내 UI를 업데이트 할 수 없다고 생각하게하는 위임자 (주 XAML 클래스)에서 항상 충돌이 발생합니다. 비동기 호출의 부산물 인 잘못된 스레드에서 불법적으로 뭔가를하려고 실수로 노력하고 있다고 생각합니다.
기본 XAML 클래스에 UI를 업데이트 할 때가되었음을 알리는 것이 더 좋거나 다른 방법이 있습니까? 나는 NotificationCenter를 사용할 수있는 IOS 세계에서 왔습니다. http://msdn.microsoft.com/en-us/library/windows/apps/hh755798.aspx
당신은 내가 내 자신의 콜백 대신이 방법을 사용하면 더 이상 충돌하지 것이라고 생각하십니까 :
는 지금, 나는 마이크로 소프트는 여기에 일의 그것의 자신의 대리자 형식을 가지고 보았다?
더 많은 설명이 필요하거나 그렇지 않은 경우 알려 주시기 바랍니다. 공용 인터페이스 클래스 ISmileServiceEvents { 공개 : 여기
코드의 JIST입니다 // 필요한 방법 가상 무효에 updateUI (BOOL 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를 업데이트 갈 때 내가 오류는 다음과 같습니다 ". 잘못된 매개 변수 치명적인 유효하지 않은 매개 변수를 고려 함수에 전달했다" 난 그냥 내 콜백에서 실행하려고이 경우 그것은 잘못된 상황에서 UI 스레드를 업데이트 표시
txtBox->Text = data;
감사합니다. 나는 끝까지 읽었고 당신이 제안한 것과 모순되는 말을합니다. 기사 출처 : " 사용 동시성 :: task_continuation_context :: use_arbitrary 계속 백그라운드 스레드에서 실행되도록 지정하려면 사용 동시성 :: task_continuation_context :: use_current 계속이 작업라는 스레드에서 실행되도록 지정합니다. : : then. " – VaporwareWolf
어느 쪽이든, 나는 둘 다 임의()로 변경하고 use_current()를 제거하려고 시도했다. 어느 누구도 문제를 해결하는 데 도움이되지 않았습니다. – VaporwareWolf