UE4 crash when using dynamic multicast delegate

It appears that your code is not currently taking thread safety into consideration. The callback function UdpReceivedCallback in your DroneUDPComponent is being called from another thread, NOT the game thread that your game code is running on.

You need to bring that data onto your game thread, I would recommend polling to do so. I would recommend running a tock, or timered function on the main thread that is consistently checking and pulling data out of a threadsafe TQueue member.

I am currently employing this mechanism in the VOIP service I am authoring:

void UVoipClient::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& Endpoint)
{
	FVoipPacket packet = FVoipPacket();
	if (packet.Validate(ArrayReaderPtr, bIsIgnoringVoice))
	{		
		RecvQueue.Enqueue(packet);
	}
}

After enqueue, I dequeue on the main thread:

void UVoipClient::Poll()
{
	if (RecvQueue.IsEmpty())
	{
		EarlyOut();
		return;
	}
	MarkThreadActive();		

	while (!RecvQueue.IsEmpty())
	{
		FVoipPacket flaggedPacket;
		RecvQueue.Dequeue(flaggedPacket);
		ParseRecv(flaggedPacket);
	}
}

I set up my polling timer as a self throttling timer, but you can set a timer pretty easily with the following code:

World->GetTimerManager().SetTimer(RecvPollingHandle, this, &UVoipClient::Poll, NewRate, true);  

of course you will need all of your the necessary parts in your .h file as well…

 FTimerHandle RecvPollingHandle;     
 void Poll();
 TQueue<FVoipPacket> RecvQueue;
 void Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& Endpoint);

This is just one way to do it, there are likely other, better ways, but this works well for our use case.
I hope this helps with your project, Let me know if you have any questions.

-Spiris

Problem:
After I open my game project, and click “Play”, I receive the following log message.

LogOutputDevice:Warning: Script Stack:
DroneBase.OnUDPRecvDataReceive
LogStats: FPlatformStackWalk::StackWalkAndDump - 0.009 s
LogOutputDevice:Error: === Handled ensure: ===
LogOutputDevice:Error: Ensure condition failed: GetShadowIndex() == 0 [File:D:\Build++UE4+Release-4.14+Compile\Sync\Engine\Source\Runtime\Core\Public\HAL\IConsoleManager.h] [Line: 798]
LogOutputDevice:Error: Stack:
LogOutputDevice:Error: UE4Editor-Core.dll
LogOutputDevice:Error: UE4Editor-Core.dll
LogOutputDevice:Error: UE4Editor-Core.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-CoreUObject.dll
LogOutputDevice:Error: UE4Editor-CoreUObject.dll
LogOutputDevice:Error: UE4Editor-Engine.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-PAIXXXX_Drone-550.dll
LogOutputDevice:Error: UE4Editor-Core.dll
LogOutputDevice:Error: UE4Editor-Core.dll
LogOutputDevice:Error: KERNEL32.DLL
LogOutputDevice:Error: ntdll.dll
LogStats: SubmitErrorReport - 0.000 s
PIE: 情報 /Game/Level/UEDPIE_0_DroneMain -0.58のプレイ イン エディタの開始時間
LogBlueprintUserMessages: Late PlayInEditor Detection: Level ‘/Game/Level/DroneMain.DroneMain:PersistentLevel’ has LevelScriptBlueprint ‘/Game/Level/DroneMain.DroneMain:PersistentLevel.DroneMain’ with GeneratedClass ‘/Game/Level/DroneMain.DroneMain_C’ with ClassGeneratedBy ‘/Game/Level/DroneMain.DroneMain:PersistentLevel.DroneMain’
LogStats: SendNewReport - 0.260 s
LogStats: FDebug::EnsureFailed - 0.269 s

The program will not crash at this moment, but if I let it run for 2-3 s, Unreal Engine will crash down.

Here is my C++ Code:
DroneUDPComponent.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Components/ActorComponent.h"
#include "Networking.h"
#include "Sockets.h"
#include "DroneRecvRawData.h"
#include "DroneRecvData.h"
#include "DroneUDPComponent.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FUdpDataReceivedDelegate, FDroneRecvData, RecvData);

UCLASS( ClassGroup=(Drone), meta=(BlueprintSpawnableComponent) )
class PAIXXXX_DRONE_API UDroneUDPComponent : public UActorComponent
{
	GENERATED_BODY()

	FSocket *Recv_Socket;
	FUdpSocketReceiver *Data_Receiver;

	/* UDPデータが届いた際に呼ばれるコールバック */
	void UdpReceivedCallback(const FArrayReaderPtr& data, const FIPv4Endpoint& endPoint);

public:	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drone UDP Communication")
		int32 RecvPort = 53909;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drone UDP Communication")
		FString IPAddress = TEXT("127.0.0.1");

	// Sets default values for this component's properties
	UDroneUDPComponent();
	~UDroneUDPComponent();

	// Called when the game starts
	virtual void BeginPlay() override;

	UFUNCTION(BlueprintCallable, category = "Drone UDP Communication")
		void Init();

	UFUNCTION(BlueprintCallable, category = "Drone UDP Communication")
		void Connect();

	void CreateRecvSocket();
	void CreateDataRecevicer();
	
	UFUNCTION(BlueprintCallable, category = "Drone UDP Communication")
	void Close();

	
	UPROPERTY(BlueprintAssignable, category = "Drone UDP Communication")
	FUdpDataReceivedDelegate OnDataReceived;
};

DroneUDPComponent.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "PAIXXXX_Drone.h"
#include "DroneUDPComponent.h"


// Sets default values for this component's properties
UDroneUDPComponent::UDroneUDPComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = false;

	// ...
}

UDroneUDPComponent::~UDroneUDPComponent()
{
	this->Close();
}

// Called when the game starts
void UDroneUDPComponent::BeginPlay()
{
	Super::BeginPlay();

	// ...
	this->Init();
}

void UDroneUDPComponent::Init() {
	CreateRecvSocket();
	CreateDataRecevicer();
}

void UDroneUDPComponent::Connect() {
	if (Recv_Socket != NULL && Data_Receiver != NULL) {
		Data_Receiver->Start();
	}
	else {
		UE_LOG(LogTemp, Error, TEXT("UDroneUDPComponent::Connect() | Socket or Receiver is null"),);
	}
}

void UDroneUDPComponent::CreateRecvSocket() {
	if (Recv_Socket == NULL) {
		FIPv4Address ip;
		FIPv4Address::Parse(this->IPAddress, ip);
		Recv_Socket = FUdpSocketBuilder(TEXT("Drone UDP Data Recv Socket"))
			.BoundToAddress(ip)
			.BoundToPort(this->RecvPort)
			.Build();

		Recv_Raw_Data = new FDroneRecvRawData();
		Recv_Data = new FDroneRecvData();

		UE_LOG(LogTemp, Log, TEXT("UDroneUDPComponent::CreateRecvSocket() | Connected to IP: %s, Port: %d"), *this->IPAddress, this->RecvPort);
	}
}

void UDroneUDPComponent::CreateDataRecevicer() {
	if (Recv_Socket != NULL) {
		/* UDP受信を開始 */
		Data_Receiver = new FUdpSocketReceiver(Recv_Socket, FTimespan(0, 0, 1), TEXT("Drone UDP Data Receiver"));

		if (!Data_Receiver)
		{
			UE_LOG(LogTemp, Error, TEXT("UDroneUDPComponent::CreateDataRecevicer() | Construct receiver failed."));
			return;
		}

		Data_Receiver->OnDataReceived().BindUObject(this, &UDroneUDPComponent::UdpReceivedCallback);

		// 接続成功
		UE_LOG(LogTemp, Log, TEXT("UDroneUDPComponent::CreateDataRecevicer() | Construct receiver success."));
	}
	else {
		UE_LOG(LogTemp, Error, TEXT("UDroneUDPComponent::CreateDataRecevicer() | Socket is null."));
	}
}

void UDroneUDPComponent::Close()
{
	if (Data_Receiver != NULL) {
		Data_Receiver->Stop();
		delete Data_Receiver;
		Data_Receiver = NULL;
	}

	if (Recv_Socket != NULL) {
		Recv_Socket->Close();
		delete Recv_Socket;
		Recv_Socket = NULL;
	}
}


void UDroneUDPComponent::UdpReceivedCallback(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& endPoint)
{
	uint32 receivedSize = ArrayReaderPtr->GetAllocatedSize();
	UE_LOG(LogTemp, Log, TEXT("%d bytes received!"), receivedSize);

	OnDataReceived.Broadcast(*Recv_Data);
}

DroneBase.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "DroneUDPComponent.h"
#include "DroneBase.generated.h"

UCLASS()
class PAIXXXX_DRONE_API ADroneBase : public AActor
{
	GENERATED_BODY()

	
public:	
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Drone")
	UDroneUDPComponent* DroneUDPCompoment;

	// Sets default values for this actor's properties
	ADroneBase();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UFUNCTION(BlueprintCallable, category = "Drone")
	void OnUDPRecvDataReceive(FDroneRecvData RecvData);

	UFUNCTION(BlueprintCallable, category = "Drone")
	void UpdatePosture(FRotator Rotator);

	UFUNCTION(BlueprintCallable, category = "Drone")
	void UpdateLocation(FVector Location);

	UFUNCTION(BlueprintCallable, category = "Drone")
	void UpdatePropeller(TArray<FVector> Propeller);
};

DroneBase.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "PAIXXXX_Drone.h"
#include "DroneBase.h"


// Sets default values
ADroneBase::ADroneBase()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	DroneUDPCompoment = CreateDefaultSubobject<UDroneUDPComponent>(TEXT("DroneUDPComponent"));
	if (DroneUDPCompoment) {
		this->AddOwnedComponent(DroneUDPCompoment);
	}
}

// Called when the game starts or when spawned
void ADroneBase::BeginPlay()
{
	Super::BeginPlay();
	DroneUDPCompoment->OnDataReceived.AddUniqueDynamic(this, &ADroneBase::OnUDPRecvDataReceive);
	DroneUDPCompoment->Connect();
}

// Called every frame
void ADroneBase::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

void ADroneBase::OnUDPRecvDataReceive(FDroneRecvData RecvData) {
	UE_LOG(LogTemp, Log, TEXT("ADroneBase::OnUDPRecvDataReceive"));

	//Just do something relate to actor location
	this->SetActorLocation(FVector(FMath::RandRange(0.0f, 10.0f), FMath::RandRange(0.0f, 10.0f), FMath::RandRange(0.0f, 10.0f)));
}

void ADroneBase::UpdatePosture(FRotator Rotator) {
	this->SetActorRotation(Rotator);
}

void ADroneBase::UpdateLocation(FVector Location) {
	FVector LocationInCM = Location * 100;

	this->SetActorLocation(LocationInCM);
}

void ADroneBase::UpdatePropeller(TArray<FVector> Propeller) {

}

I have no idea how the problem happened and how I can solve the problem.
Would anybody can give me some advise?

Is that mean I should not use delegate in this case?
I am new in UE4 and I just want to try in using delegate.

Sorry, I just misunderstanding your meaning.
After I edit my code, with the help of polling and timer, my project seem not to crash now.
Thank you very much.

While the other answer is correct, since this is the top search result I think it’s worth noting that in my (similar) case, the problem was simply because I had set PrimaryComponentTick.bRunOnAnyThread = true;, and was doing thread-unsafe stuff in TickComponent().

Therefore the solution in my case was simply to set PrimaryComponentTick.bRunOnAnyThread = false;.