locked
Accessing UI data from another thread

    Question

  • Hi,

    so basically I have a task, and in that task I want to access some UI related data, for this example, let's say I want to access CoreWindow Bounds property. Obviously CoreWindow can be accessed only from UI thread, so the only way for me to access Bounds property is to use Dispatcher.

    This is a modified code from Direct3DApp template app, here I modified SetWindow function:

    void Dispatchers::SetWindow(CoreWindow^ window) { window->SizeChanged += ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &Dispatchers::OnWindowSizeChanged); window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &Dispatchers::OnVisibilityChanged); window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &Dispatchers::OnWindowClosed); window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &Dispatchers::OnPointerPressed); window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &Dispatchers::OnPointerMoved); m_renderer->Initialize(CoreWindow::GetForCurrentThread());

    // LOOK BELOW s_Dispatcher = window->Dispatcher; create_task([this] { Rect rc; // Can't access CoreWindow from non UI thread, this will crash //rc = CoreWindow::GetForCurrentThread()->Bounds; HANDLE handle = CreateEventExW(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); s_Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([&rc, &handle]() { rc = CoreWindow::GetForCurrentThread()->Bounds; SetEvent(handle); })); WaitForSingleObjectEx(handle, INFINITE, TRUE); //Output("Bounds:%.2f %.2f", rc.Width, rc.Height); } ); }


    So here, I am creating a task, and let's say I want to get Bounds from CoreWindow (this is just an example, in other scenarios, I might need to set or do something more complex with UI)

    By using the dispatcher and events, I am able to access Bounds property inside my task and it actually works, I am wondering is there a more easier way to access UI data from a task, or are there other means to synchronize data retrievement by not using events.

    Thank you

    Tuesday, March 05, 2013 3:38 PM

Answers

  • That's probably the easiest way to get back to your original thread. You can also look into chaining your tasks. Take a look at Asynchronous programming in C++ (Windows Store apps).

    If you have a few properties that you know you'll need frequently and which won't change often (like Bounds) you can create a copy of the data so you don't need to read it from the UI thread.

    --Rob

    • Marked as answer by Jesse Jiang Monday, March 11, 2013 2:27 AM
    Tuesday, March 05, 2013 11:10 PM
    Owner