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

SQL Anywhere 11.0.1 (中文) » MobiLink - 服务器管理 » MobiLink 服务器 API » 使用 .NET 编写同步脚本 » 编写 .NET 同步逻辑

 

用户定义的启动类

可以定义在服务器启动时自动装载的启动类。利用这一功能,就可以编写当 MobiLink 服务器启动 CLR 时(在第一次同步之前)执行的 .NET 代码。这意味着您可以在服务器实例中的第一个用户同步请求之前,创建连接或高速缓存数据。

此功能是通过使用 mlsrv11 -sl dnet 选项的 MLStartClasses 选项来实现的。例如,以下是 mlsrv11 命令行的部分内容。它将使 mycl1 和 mycl2 作为启动类装载。

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

将按所列顺序装载各个类。如果多次列出同一个类,则会创建多个实例。

所有启动类必须是公共类,并且必须具有一个不接受任何参数,或接受一个类型为 MobiLink.Script.ServerContext 的参数的公共构造函数。

装载的启动类的名称输出到 MobiLink 日志,显示以下消息:"已装载 .NET 启动类classname"。

有关 .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);
            }
        }
    }
}