Reputation: 761
I'm stuck with executing a function async. For now the function is called synchronously. It stores some information on a list and provides information about the list items later.
// Read Infos
void MyManager::Read(HWND parent)
{
// do some work...
mItemInfos.push_back(info);
}
// provide information
ItemInfo* MyManager::GetInfo(int index)
{
return mItemInfos.at(index);
}
Now I want to do the reading async. I defined a new method
void MyManager::BeginRead(HWND parent)
{
mFuture = std::async(std::launch::async, &MyManager::Read, this, parent);
}
Now when an exception is thrown in the Read
method, i will never know, because the mFuture.get()
method is never called. To fix this, should I just call mFuture.get()
In GetInfo()
? Everytime I call GetInfo()
?
My whole approach seems to miss something, can anyone help me please?
Thanks in advance
Upvotes: 2
Views: 314
Reputation: 11317
Looking at the code, I see multiple issues:
.get()
multiple times on the same instance of future?For std::future
are only allowed to call .get()
once. If you want to call it multiple times, you'll need std::shared_future
which will throw every access.
So, should you call .get()
before accessing the vector? Yes, definitely. Otherwise you don't have a guarantee that the element will be in the vector.
However, you should also add some synchronization for access of the vector, as one thread could try to access it, while another creates a new future which reallocates the vector you are accessing.
Finally, why do you waste time with creating new threads? The operation itself looks cheap. Even when it isn't, I can only assume you don't want to block at that point. Unfortunately, you don't prevent blocking as the Dtor of the std::future
will block in certain cases.
Again, using std::shared_future
would prevent that, however, than you no longer have control about whether it was executed, as the second assignment lets mFuture
forget about the first one, even when not fully executed.
Upvotes: 1