Announcement

Collapse
No announcement yet.

New Core Feature: Async Framework (Master Branch and 4.8)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • replied
    Originally posted by n00854180t View Post
    There is a method to check if work is finished on the FAsyncTask, but then you do have to either wrap it in a ticked object or check it in certain intervals. I'd actually like to know if there's a way to set up an event for FAsyncTask myself as that would be a lot cleaner for some things I'm doing as well.
    We don't have continuations yet, if that's what you mean, but it's on the to-do list.

    In the meantime, you could pass a delegate as a parameter to the async function, which the async function will execute when it is complete. Make sure that your delegate handler is thread-safe.

    Leave a comment:


  • replied
    Originally posted by HateDread View Post
    Thanks for the lead! FAsyncTask looks nice (I'm used to using FRunnables, which have a bit more overhead and setup, so this is cool!)

    This doesn't handle the 2nd part, however - the execution of work on the main thread once the async portion has been completed. I can of course wrap this task with a tickable object and execute a function pointer once MyTask->IsDone() returns true, but I was hoping for something built-in. Even a function that is called on the main thread once the task has completed (and which I could override in a subclass), such as a virtual void OnTaskCompleted() function. Any ideas?
    Not sure, I don't know enough about the C++ classes to be able to say whether there's something like that. There is a method to check if work is finished on the FAsyncTask, but then you do have to either wrap it in a ticked object or check it in certain intervals.

    I'd actually like to know if there's a way to set up an event for FAsyncTask myself as that would be a lot cleaner for some things I'm doing as well.

    Leave a comment:


  • replied
    Originally posted by n00854180t View Post
    Unless I misunderstand, you should be able to accomplish what you want with the regular FAsyncTask.

    Check out the code for sound decompression, it can be used in a similar manner https://github.com/EpicGames/UnrealE...ioDecompress.h
    Thanks for the lead! FAsyncTask looks nice (I'm used to using FRunnables, which have a bit more overhead and setup, so this is cool!)

    This doesn't handle the 2nd part, however - the execution of work on the main thread once the async portion has been completed. I can of course wrap this task with a tickable object and execute a function pointer once MyTask->IsDone() returns true, but I was hoping for something built-in. Even a function that is called on the main thread once the task has completed (and which I could override in a subclass), such as a virtual void OnTaskCompleted() function. Any ideas?

    Leave a comment:


  • replied
    Originally posted by HateDread View Post
    I wonder, is there a mechanism for async work with non-blocking wait? I.e. an object ticked every frame that checks if its assigned thread/task is finished, and when that's finished, it executes some bound function and uses any data created/calculated by the thread/task to do work on the main thread. I.e. some sort of IO operation during gameplay, where you want to use the results when they're ready, but you don't want to block the game thread with a future (since you have no idea how long this loading will take; the future could halt the main thread for many frames).
    Unless I misunderstand, you should be able to accomplish what you want with the regular FAsyncTask.

    Check out the code for sound decompression, it can be used in a similar manner https://github.com/EpicGames/UnrealE...ioDecompress.h

    Leave a comment:


  • replied
    I wonder, is there a mechanism for async work with non-blocking wait? I.e. an object ticked every frame that checks if its assigned thread/task is finished, and when that's finished, it executes some bound function and uses any data created/calculated by the thread/task to do work on the main thread. I.e. some sort of IO operation during gameplay, where you want to use the results when they're ready, but you don't want to block the game thread with a future (since you have no idea how long this loading will take; the future could halt the main thread for many frames).

    Leave a comment:


  • replied
    Nice addition! Thanks for the info too.

    Leave a comment:


  • replied
    Very nice addition, giving more freedom on how we can use async primitives will let us do far more stuff!

    Thanks!

    Leave a comment:


  • replied
    Very nice! I love the async/await support in C#

    Leave a comment:


  • replied
    Nice Addition, will definitely try it asap!

    Leave a comment:


  • replied
    Very nice! I'm excited to try these, need to set aside some time to seriously dive in. Several algorithms for things I want to do would be nicer in parallel, but I don't have much experience with async in C++ so I've been putting them off.

    Thanks for the warning nick_p!

    Leave a comment:


  • replied
    Thank you Gerke for taking the time to write up this extremely helpful information!

    And thanks Nick P. for the additional info!

    I can't wait to try out the new Future/Async primitives!



    Rama

    Leave a comment:


  • replied
    As a side note, if you're using this feature be very aware of how C++ lambdas work with variable capture. It's very easy to capture a stack value by reference that you didn't intend to that can lead to race conditions!

    You can capture specific variables rather than all variables (my preference) and choose whether to capture them by-value or by-reference.

    e.g., a simple case:

    Code:
    for (int i = 0; i < SomeStuff.Num(); ++i)
    {
    	auto Future = Async<int>(EAsyncExecution::ThreadPool, [&]
    	{
    		// "i" has been captured by reference! By the time this thing runs on another thread who knows what it will be
    		// We could instead use [=] but that would copy the SomeStuff array which we probably don't want.
    		// We could use [i,&SomeStuff] to capture i by value and SomeStuff by reference. That works as long as we guarantee that the array and its contents won't change while these async operations are in-flight.
    		return DoSlowOperation(SomeStuff[i]);
    	});
    }

    Leave a comment:


  • replied
    Some more implementation details for those who care:

    Our implementation separates the read and write side of asynchronous results into two concepts: Futures and Promises. A Future is the object being returned to the caller. It can be used to retrieve a functions return value when it is needed at some time in the future. If the return value is not yet available, the calling thread will block (there is also an option to wait with a timeout). A Promise is used by the called function to write the result into the Future.

    Futures and Promises cannot be copied - they can only be moved. If you move them from one instance to another, the old instance becomes invalid and can no longer be used to set or retrieve result values; this is an optimization. If you wish to share a Future between multiple threads, you can call TFuture.Share() to create a Shared Future. Shared futures are copyable, but do not support the more efficient move semantics.

    The full implementation is in /Runtime/Core/Public/Async/Future.h. Please see the code documentation for further details.

    For a general introduction to the Future/Promise pattern check out this Wikipedia article.

    Leave a comment:

Working...
X