Hi. If a player runs my command, it crashes my server. If i run it in the console it works. I already found the issue. But I don't know what I can do. I give the player using a variable to a different class. PHP: private $ip, $port, $timeout, $server, $status, $online, $max, $type, $player;public function __construct($ip, $port, $type, $player, $timeout = 10){ $this->ip = $ip; $this->port = $port; $this->timeout = $timeout; $this->player = $player;//If I remove $this->player the server doesn't crash $this->type = $type;}
This is where I start the task. But it has something to do with the first code. It only crashes if I use $this->player = $player and $player is not the console PHP: $status = $this->getServer()->getScheduler()->scheduleAsyncTask($task = new StatusTask($ip, $port, $type, $player, $timeout));
Serialization of closure is not allowed. You can't pass a Player::class to an AsyncTask directly (assuming $player is an instance of Player).
same you still cant serialize that either there's not much exceptions to serializing classes unless it's independent(? source needed) with no attachments to other classes like a raw vec3 (? source needed) or storage classes but you can pass in names like "playername" or "@console" so you can re obtain targeted instance weather a player or console
Classes extending other classes can generally be serialized. I can't find any info on when serialisation will not be working anymore. This still works: PHP: <?phpclass SomeRandomObject{ public $aaa = "ftw"; public function test1(){ echo("test1"); }}class ComplexClass extends SomeRandomObject{ public $notThatComplex = 0; public $sth = "sth"; public $array = [0 => 'aa', 'strindex' => 4]; public function __construct(int $arrAddVal){ $array[1] = $arrAddVal; } public function test2(){ echo("test2"); }}$complexObject = new ComplexClass(10);class IwantAnObject extends Thread{ protected $myObjectAsABLOB = null; public function __construct(ComplexClass $myObject){ $this->myObjectAsABLOB = serialize($myObject); } public function run(){ echo("Thread #".$this->getThreadId()." is running.\n"); $myObject = unserialize($this->myObjectAsABLOB); var_dump($myObject); $myObject->test2(); $myObject->test1(); var_dump($myObject->aaa); }}$thread = new IwantAnObject($complexObject);$thread->start();while(true){sleep(10);}
by that i meant objects like ConsoleCommandSender and Player which hold references to things like server and so on
You can't get anything that holds \pocketmine\Server into async, that includes ConsoleCommandSender and player.
I really wanted to stop myself from posting, but all the nonsense going on here is intolerable... The OP has clearly shown that he is trying to dispatch an AsyncTask but trying to store a CommandSender object in an AsyncTask field. Mind reading the source code of ConsoleCommandSender. It does not contain any reference to the main class. That's why it can be serialized without crashing. But note. It will still not work as you intend it to. You have to note several facts: Even if you managed to get an object from the main thread into a field (a.k.a. class property) in an AsyncTask subclass, it will work as if it has been cloned, i.e. it will be useless. Therefore you should never store an object in an AsyncTask field, with the exception of purely primitive value classes (if you don't understand what these are or why not, simply read the bold words). Obviously these objects will not be useful if they are used in AsyncTask body (onRun). They are equally useless in AsyncTask finalization (onCompletion) because they are already cloned. If you really need to use an object from the main thread in an AsyncTask body (onRun) in the hope that it will reduce lag on main thread, forget it; it is impossible (and don't give me the nonsense of "nothing is impossible"). You should not use an AsyncTask for it at all. If you really need to use an object from the main thread in an AsyncTask body (onRun) to execute an intermediate main-thread handler of results from your AsyncTask (e.g. to send a message to a CommandSender to display how much data you have downloaded in an AsyncTask), use the progress publish API added in PR #100 along with the local thread storage API added in PR #1. If you really need to use an object from the main thread in an AsyncTask finalization (onCompletion), use the local thread storage API added in PR #1. I'm not going to explain PR#1 and PR#100 here as I have already done so numerous times. Search for them if you can; and I hope that someone who understands what's going on can post an explanation of my whole post here, as I think I have not elaborated things very clearly. And I hope nobody else is trying to point others as stupid, because everyone who has posted above has made some rather serious misconceptions or misunderstanding.
Yeah, it isn't like "Oh, sending players 20 custom nbt tagged items lags, let me just push that into an async task." AsyncTask isn't what can always save you from the big "sleep". Try using it to pass heavy PHP functions. Maybe a heavy 3 dimensional for loop?
Hmm, I still don't get what you are trying to accomplish here? We can always find a different method.
This is irrelevant to this thread. The OP didn't exhibit any symptoms of trying to move main-thread load-heavy tasks to AsyncTask. He probably just wanted to use it in onCompletion(). You are making assumptions Which part are you referring to?