This is my personal lab on figuring out how to do Asynchronous operations with a File Picker. When you get this figured out, it is simple. But you have to read a bunch of super perfect wordy articles that are awesome if you are used to reading C++ documentation that includes the parallel programming library (ppl) and a number of other things. If you aren’t, then there is no “minus 1” programming article. And maybe this won’t do it for you, but I know where I wrote this and I can find it again. So if you stumbled on this, my apologies the article was written for me.
The code sample is at: http://code.msdn.microsoft.com/Super-Simple-Asynchronous-0a5185e4
Add #include <ppltasks.h> to the pch.h file so I might add:
#include <string> #include <sstream> #include <vector> #include <ppltasks.h> #include <concurrent_unordered_map.h>
I add to the mainpage.xaml.cpp:
using namespace concurrency;
using namespace concurrency;
To the XAML page I add two controls, a textblock and a button.
Then I added the following code to a button click event, which appears to be unnamed, a bad practice:
void WindowsRTPicker::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
txtBlockOutput->Text = "Picked photo: " + file->Name;
txtBlockOutput->Text = "Operation cancelled.";
If you are generating the code initially, and fail to add the keyword “this” inside of the square brackets, you will see that the control names will not resolve. C++ has had a problem in the past with the name resolution from XAML controls, but the problem here is that you your create_task might look like the following, note that the “this” is missing:
create_task(openPicker->PickSingleFileAsync()).then([ ](StorageFile^ file)
XAML control names won’t resolve with the “this” keyword and that is completely annoying, so take note.
There's something I wish to ask. In the past when I write multithreaded program in C#, I need to use Control.InvokeRequired and Control.Invoke() to make sure I'm in the UI thread before changing value of text control.
Is the UI thread requirement removed or the new .NET runtime will take care of that for us, or it's just the UI thread part is neglected to make the sample simple?
The reason you need to put the "this" in the square brackets has nothing to do with XAML. The square brackets are the capture clause for the lambda - the then() function takes a lambda. In order for the lambda to work with anything from calling scope, you have to capture what you want to work with.
Thank you Kate! Yep, I should have mentioned that the "this" is for the lambda, and I didn't make it clear that the control doesn't resolve it's name inside of the lambda, but does outside of it.
Good catch and appreciated!
Please note that Kate Gregory has just finished a book titled:
C++ Amp: Accelerated Massive Parallelism with Microsoft Visual C++
Which I plan on buying when it available!
Thank you again Kate!
I didn't give the UI Thread any thought. I was in my C++ mode which stopped growing around 1993 with headless (UI) devices that I was consulted on at the time. Usually I got input from sensors and output to motors or valves.
Now that you ask that question, I will have to give it consideration.
You are the best reader!
It seems the PPL library guarantees that if the task is created on UI thread, the Async delegate will also run on UI thread. This makes many things simpler.
Threaded programming is important to be successful these days, but for the life of me, why do human programmers even have to worry about it. Like security, I think that it would be better to "train" software tools to make the correct design for threading and security. I do not want to worry my balding head about these things. But we must, we must.