Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (日本語) » Mobile Link - サーバ管理 » Mobile Link サーバ API » .NET での同期スクリプトの作成 » .NET 同期論理の作成

 

ユーザ定義起動クラス

サーバの起動時に自動的にロードされる起動クラスを定義できます。この機能の目的は、最初の同期の前に Mobile Link サーバが CLR を起動する時点で実行される .NET コードを記述できるようにすることです。つまり、サーバ・インスタンスで、最初のユーザ同期要求の前に、接続の作成またはデータのキャッシュを実行できます。

この操作を行うには、mlsrv11 -sl dnet オプションの MLStartClasses オプションを使用します。たとえば、次に示すのは mlsrv11 コマンド・ラインの一部です。mycl1 と mycl2 が起動クラスとしてロードされます。

-sl dnet(-MLStartClasses=MyNameSpace.MyClass.mycl1,MyNameSpace.MyClass.mycl2)

クラスはリスト内の順序でロードされます。同じクラスがリストに 2 回以上指定されている場合は、複数のインスタンスが作成されます。

すべての起動クラスはパブリックでなければなりません。また、引数を 1 つも受け付けないか、または MobiLink.Script.ServerContext データ型の引数を 1 つ受け付けるパブリック・コンストラクタが必要です。

ロードされた起動クラスの名前は、「.NET 起動クラス classname がロードされました。」というメッセージとともに Mobile Link ログに出力されます。

.NET CLR の詳細については、-sl dnet オプションを参照してください。

サーバ起動時に構築される起動クラスを表示する方法については、GetStartClassInstances メソッドを参照してください。

次に示すのは、起動クラスのテンプレートです。これは、イベントを処理してデータベース接続を確立するデーモン・スレッドを起動します(すべての起動クラスがスレッドの作成を必要とするわけではありませんが、スレッドを作成する場合はデーモン・スレッドでなければなりません)。

using System;
using System.IO;
using System.Threading;
using iAnywhere.MobiLink.Script; 

namespace TestScripts {
    public class MyStartClass {
        ServerContext    _sc;
        bool             _exit_loop;
        Thread           _thread;
        OdbcConnection   _conn;

        public MyStartClass(ServerContext sc) {

            // Perform setup first so that an exception 
            // causes MobiLink startup to fail.
            _sc = sc;

            // Create connection for use later.
            _conn = _sc.makeConnection();
            _exit_loop = false;
            _thread = new Thread(new ThreadStart(run)) ;
            _thread.IsBackground = true;
            _thread.Start();
        }

        public void run() {
            ShutdownCallback callback = new ShutdownCallback(shutdownPerformed);
            _sc.ShutdownListener += callback;

            // run() can't throw exceptions.
            try {
                handlerLoop();
                _conn.close();
                _conn = null;
            }
            catch(Exception e) {
                // Print some error output to the MobiLink log.
                Console.Error.Write(e.ToString());
     
                // There is no need to be notified of shutdown.
                _sc.ShutdownListener -= callback;

                // Ask server to shut down so this fatal error can be fixed.
                _sc.Shutdown();
            }

            // Shortly after return, this thread no longer exists.
            return;
        }

        public void shutdownPerformed(ServerContext sc) {
            // Stop the event handler loop.
            try {
                _exit_loop = true;
    
                // Wait a maximum of 10 seconds for thread to die.
                _thread.Join(10*1000);
            } 
            catch(Exception e) {
                // Print some error output to the MobiLink log.
                Console.Error.Write(e.ToString());
            }
        }

        private void handlerLoop() {
            while (!_exit_loop) {
                // Handle events in this loop.
                Thread.Sleep(1*1000);
            }
        }
    }
}