Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to keep track of pending IAsyncActions #1430

Closed
amtopel opened this issue Aug 6, 2024 · 4 comments
Closed

Best way to keep track of pending IAsyncActions #1430

amtopel opened this issue Aug 6, 2024 · 4 comments

Comments

@amtopel
Copy link

amtopel commented Aug 6, 2024

Version

No response

Summary

This isn't a bug. Just a question.

Let's say you have a long-running application that fires off a bunch of methods on the threadpool using winrt::resume_background(). And then when it's time to close the app, you'd like to wait for any in-flight tasks to finish up.

I understand that there are functions like winrt::when_all that allow you to wait on a bunch of IAsyncActions. Or you can loop through a vector of IAsyncActions and co_await them, as discussed here.

But my question is: what's the best strategy for keeping a hold on your pending IAsyncActions so that you know the ones to wait on when it's time to quit? Is there a specific class or function for that?

Granted, you could just store each and every IAsyncAction in a vector, but for a long-running app that may fire off hundreds or thousands of tasks, it seems like that vector would get really large and inefficient--especially since, as a practical matter, there are probably only one or two outstanding tasks to wait on when it's time to quit.

Perhaps there could be a class that acts like a vector for storing IAsyncActions, except it would remove each one upon completion. But that would monopolize the IAsyncAction's delegate, wouldn't it?

Or is it better to use a latch (i.e., reverse semaphore) in this situation?

Thanks for any information or guidance.

Reproducible example

No response

Expected behavior

No response

Actual behavior

No response

Additional comments

No response

@amtopel amtopel changed the title Best way to keep tracking of pending IAsyncActions Best way to keep track of pending IAsyncActions Aug 6, 2024
@sylveon
Copy link
Contributor

sylveon commented Aug 6, 2024

I have been doing the following:

std::mutex m_asyncSetLock;
std::unordered_set<winrt::Windows::Foundation::IAsyncAction> m_inflightAsync;

void Foo::registerInflightAsync(winrt::Windows::Foundation::IAsyncAction async)
{
    async.Completed({ this, &Foo::unregisterInflightAsync });

    std::scoped_lock guard(m_asyncSetLock);
    m_inflightAsync.insert(std::move(async));
}

void Foo::unregisterInflightAsync(const winrt::Windows::Foundation::IAsyncAction& async, winrt::Windows::Foundation::AsyncStatus status)
{
    std::scoped_lock guard(m_asyncSetLock);
    m_inflightAsync.erase(async);
}

It does, as you say, monopolize the Completed handler.

@amtopel
Copy link
Author

amtopel commented Aug 6, 2024

Thanks a lot. So then how do you use it at the end of an application if you can’t co_await the actions?

@sylveon
Copy link
Contributor

sylveon commented Aug 6, 2024

At the end of the application, I just hard-block with .get() on each action consecutively.

@amtopel
Copy link
Author

amtopel commented Aug 6, 2024

Oh yeah, that makes sense. Thanks again.

@amtopel amtopel closed this as completed Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants