0

Basically, what is happening is when trying to change a variable of a Managed class (UWP), it crashes. Additionally, it seems to only crash if I try modifying a variable which is created with the app namespace. In other words, if I create a new namspace and managed class, I can modify variables just fine.

crash

void ASynTaskCategories(void)
    {
        concurrency::task_completion_event<Platform::String^> taskDone;
        MainPage^ rootPage = this;
        UberSnip::HELPER::ASYNC_RESPONSE^ responseItem = ref new UberSnip::HELPER::ASYNC_RESPONSE();
        create_task([taskDone, responseItem, rootPage]() -> Platform::String^
        {

            //UBERSNIP API 0.4
            UberSnip::UBERSNIP_CLIENT* UberSnipAPI = new UberSnip::UBERSNIP_CLIENT();

            UberSnipAPI->Http->RequestURL = "http://api.ubersnip.com/categories.php";
            UberSnipAPI->Http->request();
            taskDone.set(UberSnipAPI->Client->BodyResponse);
            responseItem->Body = UberSnipAPI->Client->BodyResponse;
            return "(done)";

        }).then([taskDone, responseItem, rootPage](Platform::String^ BodyResponse) {
            Platform::String^ BR = responseItem->Body;


            cJSON* cats = cJSON_Parse(_string(BR));
            cats = cats->child;
            int *cat_count = new int(cJSON_GetArraySize(cats));
            rootPage->Categories->Clear();

            GENERIC_ITEM^ all_item = ref new GENERIC_ITEM();
            all_item->Title = "All";

            rootPage->Categories->Append(all_item);
            for (int i = 0; i < *cat_count; i++) {
                cJSON* cat = new cJSON();
                cat = cJSON_GetArrayItem(cats, i);

                string *track_title = new string(cJSON_GetObjectItem(cat, "name")->valuestring);

                GENERIC_ITEM gitem;
                gitem.Title = "Hi";

                GENERIC_ITEM^ ubersnipCategory = ref new GENERIC_ITEM();
                ubersnipCategory->Title = _String(*track_title);

                rootPage->Categories->Append(ubersnipCategory);
            }
        });

This does not crash

UberSnipAPI->Http->RequestURL = "http://api.ubersnip.com/categories.php";

but this one does

all_item->Title = "All";

I am almost positive it has something to do with it being in the apps default namespace and it being accessed outside of the main thread ... At least that's what it seems like as that's really the only difference besides the actual class.

This is what GENERIC_ITEM looks like.

[Windows::UI::Xaml::Data::Bindable]
public ref class GENERIC_ITEM sealed {
private:
    Platform::String^ _title = "";
    Platform::String^ _description;
    Windows::UI::Xaml::Media::ImageSource^ _Image;

    event PropertyChangedEventHandler^ _PropertyChanged;

    void OnPropertyChanged(Platform::String^ propertyName)
    {
        PropertyChangedEventArgs^ pcea = ref new  PropertyChangedEventArgs(propertyName);
        _PropertyChanged(this, pcea);
    }
public:
    GENERIC_ITEM() {

    };

    property Platform::String^ Title {
        Platform::String^ get() {
            return this->_title;
        }

        void set(Platform::String^ val) {
            this->_title = val;
            OnPropertyChanged("Title");
        }
    }

    property Platform::String^ Description {
        Platform::String^ get() {
            return this->_description;
        }

        void set(Platform::String^ val) {
            this->_description = val;
            OnPropertyChanged("Description");
        }
    }

    void SetImage(Platform::String^ path)
    {
        Windows::Foundation::Uri^ uri = ref new Windows::Foundation::Uri(path);
        _Image = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage(uri);
    }

};

I know there is no issue with the class because it works perfectly fine if I run this exact same code on the initial thread.

Any suggestions? Thanks! :D

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
user2292759
  • 159
  • 1
  • 9

1 Answers1

0

Figured it out after several hours! In case someone else is having this issue, all you must do is use the Dispatcher to run code on the UI that is not available outside of the UI thread.

void loadCats(UberSnip::HELPER::ASYNC_RESPONSE^ responseItem, MainPage^ rootPage) {
    Platform::String^ BR = responseItem->Body;


    cJSON* cats = cJSON_Parse(_string(BR));
    cats = cats->child;
    int *cat_count = new int(cJSON_GetArraySize(cats));
    rootPage->Categories->Clear();

    GENERIC_ITEM^ all_item = ref new GENERIC_ITEM();
    all_item->Title = "All";

    rootPage->Categories->Append(all_item);
    for (int i = 0; i < *cat_count; i++) {
        cJSON* cat = new cJSON();
        cat = cJSON_GetArrayItem(cats, i);

        string *track_title = new string(cJSON_GetObjectItem(cat, "name")->valuestring);

        GENERIC_ITEM gitem;
        gitem.Title = "Hi";

        GENERIC_ITEM^ ubersnipCategory = ref new GENERIC_ITEM();
        ubersnipCategory->Title = _String(*track_title);

        rootPage->Categories->Append(ubersnipCategory);
    }
}

void ASyncTaskCategories(void)
{
    concurrency::task_completion_event<Platform::String^> taskDone;
    MainPage^ rootPage = this;
    UberSnip::HELPER::ASYNC_RESPONSE^ responseItem = ref new UberSnip::HELPER::ASYNC_RESPONSE();

    auto dispatch = CoreWindow::GetForCurrentThread()->Dispatcher;
    auto op2 = create_async([taskDone, responseItem, rootPage, dispatch] {
        return create_task([taskDone, responseItem, rootPage, dispatch]() -> Platform::String^
        {

            //UBERSNIP API 0.4
            UberSnip::UBERSNIP_CLIENT* UberSnipAPI = new UberSnip::UBERSNIP_CLIENT();

            UberSnipAPI->Http->RequestURL = "http://api.ubersnip.com/categories.php";

            try{
                UberSnipAPI->Http->request();
            }
            catch (...) {
                printf("Error");
            }

            int err = UberSnip::UTILS::STRING::StringToAscIIChars(UberSnipAPI->Client->BodyResponse).find("__api_err");

            if (err < 0) {
                if (UberSnip::UTILS::STRING::StringToAscIIChars(UberSnipAPI->Client->BodyResponse).length() < 3) {
                    return;
                }
            }
            taskDone.set(UberSnipAPI->Client->BodyResponse);
            responseItem->Body = UberSnipAPI->Client->BodyResponse;
            dispatch->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([=]()
            {
                rootPage->loadCats(responseItem, rootPage);
            }));

            for (int i = 0; i < 100;) {

            }


            return "(done)";

        }).then([taskDone, responseItem, rootPage](Platform::String^ BodyResponse) {
        });

    });

        //rootPage->loadCats(responseItem, rootPage);
}
user2292759
  • 159
  • 1
  • 9