Is The principle of FNonAbandonableTask and UBlueprintAsyncActionBase implementation multi-threaded concurrency?

DECLARE_DYNAMIC_DELEGATE_OneParam(FSwitchQGCJoystickDelegate, EJoystick, type);
class TaskExample : public FNonAbandonableTask
{

	/*Code*/
public:
	FSwitchQGCJoystickDelegate SwitchJoystickDelegate;
	EJoystick Type;


	TaskExample(FSwitchQGCJoystickDelegate switchJoystickDelegate, EJoystick type = EJoystick::EJ_FengHuang)
	{
		this->SwitchJoystickDelegate = switchJoystickDelegate;
		this->Type = type;
		/*Code*/
	}

	FORCEINLINE TStatId GetStatId() const
	{
		RETURN_QUICK_DECLARE_CYCLE_STAT(TaskExample, STATGROUP_ThreadPoolAsyncTasks);
	}


	void DoWork()
	{
		/*Code*/
  
		AsyncTask(ENamedThreads::GameThread, [&]() {
			/*Code*/
		});
	}
};
UCLASS()
class AIRSIMPX4CONNECT_API USwitchQgcJoystick : public UBlueprintAsyncActionBase
{
	
	GENERATED_BODY()
public:
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBPPin_Result, EJoystick, JoystickType);

	UPROPERTY(BlueprintAssignable)
	FBPPin_Result OnComplete;

	EJoystick ActiveJoystickType;

public:

	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", Category = "AirsimPx4Connect"))
		static USwitchQgcJoystick* SwitchQgcJoystickAsync(UObject* WorldContextObject, EJoystick Type = EJoystick::EJ_FengHuang);
protected:

	virtual void Activate() override;
};

Yes and no, respectively.

BlueprintAsyncActions are still run on the game thread. As eblade pointed out in your other thread, you could start work on another thread from a BlueprintAsyncAction but that’s not usually how they get used, at least not that I’ve ever seen. Usually they just tick (on the game thread) or leverage whatever delegates the code they’re calling uses normally.

FNonAbadonableTask is definitely used with multi-threading. Personally I haven’t had a whole lot of good experience with AsyncTask (but that may just be bad uses). If you have additional code you want to run on the game thread when it’s done you might consider just giving the class another function to call. Whatever code starts the async task can hold onto it and when it’s complete, call that second function. I’ve found this to work out pretty well for managing async tasks related to save game operations.

1 Like