alielie
7 天以前 e57938fbda9bff702004038f76d009422968bff5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using DeviceService.Device;
using DeviceService.Entity;
using DeviceService.Logging;
using DeviceService.Service.NamePipe;
using System.Windows;
 
namespace DeviceService.Service
{
    public enum ServiceStatus
    {
        Idle = 0,
        Running = 1,
        Error = 2,
    }
 
    public class ServiceStateMachine : NotifyBase
    {
        public static ServiceStateMachine GlobalState = new ServiceStateMachine();
 
        private ServiceStateMachine()
        {
 
        }
 
        private ServiceStatus _state;
        public ServiceStatus State
        {
            get => _state;
            set
            {
                SetProperty(ref _state, value);
            }
        }
 
        private bool _isRunning;
        public bool IsRunning
        {
            get => _isRunning;
            set
            {
                SetProperty(ref _isRunning, value);
            }
        }
 
    }
 
    public class ServiceManager
    {
        private static IService _serviceImpl;
 
        private const string PipeName = "DeviceService";
 
        public static void Start()
        {
            if (ServiceStateMachine.GlobalState.State == ServiceStatus.Running)
            {
                MessageBox.Show("已启动");
                return;
            }
            _serviceImpl = new NamePipeService(PipeName);
            _serviceImpl.DataReceived += PipeService_DataReceived;
            _serviceImpl.ClientConnected += PipeService_ClientConnected;
            _serviceImpl.ClientDisConnected += PipeService_ClientDisConnected;
 
            string err = string.Empty;
            bool allDone = true;
 
            foreach (var device in DeviceHelper.AllDevices)
            {
                if (!DeviceManager.Register(device, out string fail))
                {
                    allDone = false;
                    err += $"{fail}\r\n";
                }
            }
 
            if (!allDone && MessageBox.Show(err, "提示", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
            {
                DeviceManager.UnRegisterAll();
                ServiceStateMachine.GlobalState.State = ServiceStatus.Error;
                return;
            }
 
 
            if (!_serviceImpl.Start(out string msg))
            {
                GlobalLogger.Logger.Error("ServiceManager", $"[服务] 管道服务启动失败:{msg}");
                Stop();
                // Stop 会把状态置为 Idle,这里再标记为异常,供界面显示
                ServiceStateMachine.GlobalState.State = ServiceStatus.Error;
                throw new Exception(msg);
            }
            ServiceStateMachine.GlobalState.State = ServiceStatus.Running;
        }
 
        public static void Stop()
        {
            if (_serviceImpl == null)
            {
                return;
            }
 
            _serviceImpl.DataReceived -= PipeService_DataReceived;
            _serviceImpl.ClientConnected -= PipeService_ClientConnected;
            _serviceImpl.ClientDisConnected -= PipeService_ClientDisConnected;
            _serviceImpl.Stop(out _);
            _serviceImpl.Dispose();
            _serviceImpl = null;
            ServiceStateMachine.GlobalState.State = ServiceStatus.Idle;
        }
 
 
        private static void PipeService_DataReceived(object? sender, RequestArg e)
        {
            // 数据到达事件来自后台线程,需要切换到 UI 线程显示
            DeviceManager.HandleClientMessage(e);
        }
 
        private static void PipeService_ClientConnected(object? sender, IClient client)
        {
            // 连接/断开事件来自后台线程,列表更新需切换到 UI 线程
 
        }
 
        private static void PipeService_ClientDisConnected(object? sender, IClient client)
        {
 
        }
    }
}