問題: 非同期で取得した受信データをレンダリングしようとすると、クラッシュします。
アプリが起動し、XAML を使用していくつかのダイアログ ボックスが表示されます。ユーザーがデータを入力してログイン ボタンをクリックすると、XAML クラスには、(IXMLHTTPRequest2 を使用して非同期的に) HTTP 処理を行うワーカー クラスのインスタンスが含まれます。アプリが Web サーバーに正常にログインすると、.then() ブロックが起動し、メインの xaml クラスへのコールバックを作成してアセットのレンダリングを行います。
ただし、デリゲート (メインの XAML クラス) で常にクラッシュが発生するため、このアプローチ (純粋な仮想クラスとコールバック) を使用して UI を更新することはできないと思います。非同期呼び出しの副産物である不適切なスレッドから、不注意に違法なことをしようとしていると思います。
メインの XAML クラスに、UI を更新する時期であることを通知するためのより良い方法または別の方法はありますか? 私は NotificationCenter を使用できる iOS の世界から来ています。
ここで、マイクロソフトには独自のデリゲート タイプのものがあることがわかりました。
独自のコールバックの代わりにこのアプローチを使用すると、クラッシュしなくなると思いますか?
さらに明確にする必要があるかどうかを教えてください。
コードの概要は次のとおりです。 public interface class ISmileServiceEvents { public: // 必要なメソッド virtual void UpdateUI(bool isValid) abstract; };
// 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());
}
編集:ところで、UI を更新するときに発生するエラーは、「無効なパラメーターが致命的であると見なす関数に無効なパラメーターが渡されました」です。この場合、コールバックで実行しようとしているのは
txtBox->Text = data;