Broadcasting events from third party thread

Hi dear Unreal Community,

I have a Blueprint class written in C++ under a plugin which do data acquisition on some custom built in-house devices.

Since I do realtime data acq1uisition and that I want ultra-fast response times, my class creates his own thread using Windows API.

When I receive data inside my thread, I broadcast it using

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDataReceivedEvent, FString, Data);

UCLASS()
class ADataServer : public AActor
{
GENERATED_UCLASS_BODY()

UPROPERTY(BlueprintAssignable, BlueprintCallable)
FDataReceivedEvent DataEvent;

}

In my thread loop I have:

EnterCriticalSection(&m_csDataLock);

if (m_fsCumulatedData != "")
{
    FString Data = m_fsCumulatedData;

    DataEvent.Broadcast(Data);
    m_fsCumulatedData = "";
}

LeaveCriticalSection(&m_csDataLock);

Of course, when a DataEvent is broadcasted, it causes a crash in the Editor since the Blueprint execution chain gets executed by an external thread.

My question is: Is there a way to do it anyway without causing a crash ?

If I put the above code within the AActor’s Thick function, I get no crash, but I would prefer it being called inside my thread to avoid any delay.

You must execute all broadcasting with Game Thread.

From your own thread you can create a simple dispatch and pass some data attached, send it to Game Thread and wait until it is “ready” to execute that event.

There’s plenty examples inside source code of Unreal Engine (and also within my SaveGame plugin lol)

I’ve shipped 3 apps that use TCP to communicate between backend objects in a separate process to Unreal frontend objects.

The specific approach used:

  • spawn your communications system on a separate thread in your GameInstance (since it is the only persistent thing)
  • queue up incoming messages
  • during GameMode.Tick() read incoming messages and dispatch messages to relevant Unreal objects

This way your Unreal objects don’t need to be made thread safe (which I’m not sure is even possible without a lot of pain).

That is terrible idea.
You’ve just made your netcode framerate dependent.

Thank you fopr the answers.

That is in fact what I was doing: breadcasting events from the game thread while acquiring data in my own thread. Since it makes it framerate dependant, I wanted to broadcast from my own thread.

That’s ok if it can not be achieved. It is exactly what I expected. I was asking the question in case of there would be a magical way to do it :slight_smile:

In fact, it seems It is pointless to have my own threads and that I should also get the data into the Tick function since I pass it to that function anyway.

Maybe if I could just change the Tick framerate of my actor it would do the job.

But it can be done without a tick, you have to take a look at engine source and see how threaded services’ “DoWork()” function is used.

I’ve been using “fire and forget” threads a lot… From these treads I delegate a simple static function that usually copy data (a struct as a copy) from my thread, sending it to Game “named” thread and immediately executing (making code thread safe)
​​​​​

I would post code, but I am on phone now, away from Pc.

[USER=“434”]BrUnO XaVIeR[/USER] Hi, can you post your code please, im trying to join an Unreal thread from my own custom c++ class.

Regarts!

That’s a post from 2018.
I don’t even remember anymore which project it was, much less the code I wrote for them.

I would also be interested in more information on how to dispatch events from third party thread to the game thread.

Or to know which modules of the engine use this so I know where to search in the engine code for example implementations.

#include "Async/Async.h"

static TWeakObjectPtr<USomeObject> ObjRef;

void some_external_thread_callback()
{
    AsyncTask(ENamedThreads::GameThread, []() {
        if (ObjRef.IsValid())
            ObjRef->SomeEvent.Broadcast();
    });
}
2 Likes

Thank you for the example !

I ended up solving my problem with a TCircularQueue as in Rama Code: Multi-Threading in UE5 C++ | Community tutorial.

Basically the network thread queue data into the queue each time they receive a message, and I dequeue data from that queue in the game thread every frame and broadcast events based on the dequeued data.