//必须设置LocalDevice之后才能运行
        public void Start()
        {
            Preconditions.Check(LocalDevice != null, "Local Device Must be set before start");
            if (isRunning)
            {
                return;            //TODO 是否需要同步锁定?有没有别的实现?
            }
            isRunning = true;

            Discoverer.StartBroadcast();
            Discoverer.StartListen();
            ChannelManager.Start();
        }
        //Mutex appModelMutex;

        private AppModel(Env container)
        {
            //container.Logger.Error("Test Log");
            var cfg = Env.Instance.Config;

            Devices       = new HashSet <Device>();
            Conversations = new Dictionary <string, Conversation>();
            LocalDevice   = cfg.LocalDevice;
            var sm = Env.Instance.SecurityManager;
            var localConnectCode = sm.LoadString(SecurityManager.LOCAL_CONNECT_CODE);

            if (localConnectCode == null)
            {
                localConnectCode = StringHelper.NewRandomPassword();
                sm.SaveString(SecurityManager.LOCAL_CONNECT_CODE, localConnectCode);
            }
            LocalDevice.ConnectCode = localConnectCode;
            LocalDevice.DeviceType  = container.DeviceType;
            container.InitLocalDeviceIPAdress(LocalDevice);



            ChannelManager = new ChannelManager(ChannelPort);
            ChannelManager.ChannelCreated += (channel) =>
            {
                Action <Packet> packetReceiver = null;
                packetReceiver = (Packet packet) =>
                {
                    Message        message = Message.FromPacket(packet);
                    ConnectMessage cm      = message as ConnectMessage;
                    //一个新连接的socket,在发送ConnectMessage之前发送其它Message,是不会理会的。
                    if (cm != null)
                    {
                        channel.PacketReceived -= packetReceiver;
                        var device = AddOrUpdateDevice(cm.Device);
                        if (device != null)
                        {
                            if (PacketHeader.DefaultVersion == packet.Header.version)
                            {
                                device.OnConnectMessageReceived(channel, cm);
                            }
                            else
                            {
                                device.CallPacketProtocolVersionError(PacketHeader.DefaultVersion > packet.Header.version);
                            }
                        }
                    }
                    ;
                };
                channel.PacketReceived += packetReceiver;
            };
            ChannelManager.PortOccupiedError += (int port) =>
            {
                Error error = new Error(Error.PortOccupied);
                error.AddError("port", port);
                ErrorHappened?.Invoke(error);
            };

            Discoverer = new LANDiscoverer(LocalDevice, DiscoverPort);
            container.NetworkChanged += (ips) =>
            {
                if (!string.IsNullOrEmpty(ips))
                {
                    container.InitLocalDeviceIPAdress(LocalDevice);
                    Discoverer.StartBroadcast();
                }
            };
        }