locked
Exception accessing XAML controls inside a task

    Question

  • If I try to access XAML controls inside a task (and task::then) my Metro XAML app always stops with an exception.
    The same code works without any problems outside the task. I didn't find any answer - what did I miss?

    VS11 Debugger reports: Concurrency::unobserved_task_exception

    Exception: The application called an interface that was marshalled for a different thread.

    Many thanks for your help!


    void MyClass::MyMemberFunction()
    {
        xamlStoryboard->Stop(); // ok
        xamlImage->Source = ref new BitmapImage(); // ok

        task<void> atask([this] ()
        {
            xamlStoryboard->Stop(); // exception!
            xamlImage->Source = ref new BitmapImage(); //exception!
        });

        atask.then([this] ()
        {
            xamlStoryboard->Stop(); // exception!
            xamlImage->Source = ref new BitmapImage(); //exception!
        });
    }

    Thursday, May 10, 2012 8:37 AM

Answers

All replies

  • Hello,

     

    How about  task<void> atask([this, xamlStoryboard] (){}?

     

    As far as I know, the this pointer to the capture clause to provide access to the methods and data members of the enclosing class.

     

    So where do you define the xamlStoryboard

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Friday, May 11, 2012 5:21 AM
  • Hello Jesse,

    xamlStoryboard is defined in MyClass.xaml


    task<void> atask([this, xamlStoryboard] (){}

    VS11 Error: Member MyClass::xamlStoryboard is not a variable


    But I found:

    Creating Asynchronous Operations in C++ for Metro style Apps
    http://msdn.microsoft.com/en-us/library/hh750082(v=vs.110).aspx

    Chapter "Controlling the Execution Thread" explains, why it isn't possible to directly access XAML controls from inside the task.
    Maybe I can use the controls dispatcher?
    But I further don't unterstand, why I get exceptions in the task::then continuation code. I thought task::then is the callback code executed after the task finishes and runs in the main thread with access to UI/XAML controls?

    best regards,
    Tobias

    Friday, May 11, 2012 9:08 AM
  • If you pass task_continuation_context::use_current() as a second parameter to the 'then' method then your callback will be scheduled as expected without needing to use the Dispatcher.

    For further info see Asynchronous programming in C++ about 2/3 of the way down in 'Managing the thread context'.


    http://babaandthepigman.spaces.live.com/blog/

    Friday, May 11, 2012 10:33 AM
  • Thanks BabaAndThePigman for the solution!

    Working code is (see postings and links for details):

    void MyClass::MyMemberFunction()
    {
        xamlStoryboard->Stop(); // ok
        xamlImage->Source = ref new BitmapImage(); // ok

        task<void> atask([this] ()
        {
            xamlStoryboard->Stop(); // exception!
            xamlImage->Source = ref new BitmapImage(); //exception!
        });

        atask.then([this] ()
        {
            xamlStoryboard->Stop(); // ok
            xamlImage->Source = ref new BitmapImage(); // ok
        }, task_continuation_context::use_current()); // that parameter SOLVED the described problems!
    }

    Friday, May 11, 2012 11:17 AM