読者です 読者をやめる 読者になる 読者になる

Xojo日本語ブログ

マルチプラットフォーム対応アプリが開発できるXojoのブログです。

重たい処理はスレッド&コールバックを使いましょう

XojoでWebアプリケーションを開発すると分かるのですが、JavaScript側では殆ど処理は行っていません。データをサーバサイドに送り、サーバ側で処理を行った結果をWebブラウザに返却します。その結果を受け取り、UIの更新を行うのがクライアントサイドの役割です。

つまり、処理的にはクライアントサイドだけで済むものであったとしても、一旦サーバ側に送られるのでネットワーク処理分の遅延が発生します。これにさらにデータベース側の処理であったり、メール処理などが重なると処理の遅れが気になるようになるかも知れません。

そこで使ってみたいのがスレッド処理になります。スレッド処理はメインとは別なプロセスを立ち上げて処理を行う仕組みです。

スレッドを使わない場合

スレッドを使わない場合、処理は次のように行われます。

f:id:moongift:20160718095733p:plain

処理は線形で、データベースなどの処理が終わらないと次の処理に進めません。JavaScriptのコールバック方式で苦しんだ経験がある人にとってはこちらの方が分かりやすいかも知れませんが、UIが絡む場合はユーザのストレスにつながりやすいのが欠点です。

スレッドを使う場合

スレッドを使うと次のようになります。

f:id:moongift:20160718095748p:plain

メインの処理とは別なプロセスになるので、まずは画面を更新してしまって、その後データベースなどの重たい処理を行うようになります。ユーザは別な処理が行えますので続けてデータ入力を行うと言った場合にも利用できます。

スレッドはライブラリのスレッドから追加できます。

f:id:moongift:20160722170611p:plain

また、Webアプリケーションとしてスレッドを使う場合は Superクラスを WebThread に設定してください。右上のインスペクタボタンを押して、スレッドのSuperの設定を変更してください。

f:id:moongift:20160725152404p:plain

なお、スレッドは引数を渡せないので注意してください。情報を渡す場合にはプロパティを使います。

' スレッドのインスタンス作成
Dim t as new backThread

' スレッドのプロパティに情報追加
t.message = TaskField.Text

' UIの処理は最初に行ってしまう
TaskList.AddRow(TaskField.Text)
TaskField.Text = ""

' スレッドの実行
t.run

スレッドの後はコールバックを呼びましょう

スレッド処理からのUIの操作や更新は基本的には避けたほうが良いでしょう。スレッド側は並列処理になるので、予期しないタイミングでUIが更新されたり、入力した内容が消えたりする可能性があります。

そこでスレッド側では最後にメッセージを返すようにし、それをメソッド側で受け取るようにしましょう。

Sub Run()
  // 何かの処理
  
  // 処理が成功した場合は空文字
  TaskManagerPage.Callback("")
  
  // エラーが起きた場合はエラーメッセージ
  TaskManagerPage.Callback("Error!")
End Sub

UIの変更はコールバック側で行うようにした方が良いでしょう。

Sub Callback(str as String)
  // 文字列の有無で処理判定
  If str <> "" Then
    // エラー
    // 画面にエラーメッセージを表示など
  Else
    // 何もしない
  End If
End Sub

重たい処理をメインスレッドで行おうとすると、UIが固まったようになってしまったり、ユーザは次の入力を行えずにイライラしてしまいます。スレッド化による並列処理を使ってスムーズな操作を実現してください。