まずAsyncTaskとは
AsyncTaskは別スレッドで動くタスク、サーバーのスレッドとは切り離されているもの。
IOとかに使う。
'AsyncTask'はどのあたりがうれしいのか
非同期だから、サーバーに影響がないこと
例えばデータベースのデータを取得するとき、同期的な処理(onEnableから直接呼び出したりするとき)だと固まる。特にデータの数が多い時は非常にまずい。
そういったときに使えるのがAsyncTask
サンプルコード
https://gist.github.com/famima65536/00e655754585016d59dddbaaa69950c5 より
<?php
/**
* Created by PhpStorm.
* User: tokai
* Date: 2018/03/01
* Time: 19:35
*/
namespace MasterF\PocketMineGUI\task;
use pocketmine\scheduler\AsyncTask;
use pocketmine\Server;
class GUIConnectionTask extends AsyncTask
{
/**
* Actions to execute when run
*
* @return void
*/
public function onRun()
{
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, "127.0.0.1",20132);
$message = socket_read($sock, 512, PHP_NORMAL_READ);
$this->setResult($message, false);
}
public function onCompletion(Server $server)
{
$message = $this->getResult();
$server->getLogger()->info("From PocketMineGUI: ${message}");
}
}
このコードではソケットを使っているため、socket_connect()
socket_read()
の部分で一時的に動作が止まる
もし、これをサーバーと同じスレッドで実行してしまうとサーバーに入れないどころか、サーバー自体の動作も停止してしまう。
そのためにIO関連ではAsncTaskを使う。
しかしうれしくない点もある。
onRunの中ではサーバー側のスレッドにアクセスできないこと
一見便利に見えるがonRunの中ではサーバー側のメソッドなどが実行できない。
その対策としてonComplete()
とsetResult(), getResult()
がある。
これらを使うことでこの問題は解決する
onComplete()
はAsyncTaskの実行が終了してから呼び出される。このメソッドはサーバーと同じスレッドで動くため、サーバー側のアクセスすることが可能だ。
setResult(), getResult()
を活用するとonRun
とonComplete()
の間で値の橋渡しができる
これでサーバー側に結果を送り付けることができる。やったぜ。
こんな感じでAsyncTaskの使い方の解説を終わります。