alielie
2025-11-25 006c98e5650b530e5220f279c1e803fefe69d40d
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 System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
 
namespace ConnectionUtil
{
    public class PipeClient2 : IDisposable
    {
        private readonly string _pipeName;
        private readonly string _serverName;
        private readonly CancellationTokenSource _cancellationTokenSource;
        private readonly ReaderWriterLockSlim _lock;
        private NamedPipeClientStream _pipeClient;
        private bool _isDisposed;
        private bool _isConnected;
        private Thread _receiveThread;
 
        // 事件定义
        public event EventHandler<PipeDataEventArgs> OnData;
        public event EventHandler OnConnected;
        public event EventHandler OnDisconnected;
 
        public PipeClient2(string pipeName, string serverName = ".")
        {
            _pipeName = pipeName;
            _serverName = serverName;
            _cancellationTokenSource = new CancellationTokenSource();
            _lock = new ReaderWriterLockSlim();
        }
 
        public void Connect(int timeoutMs = 5000)
        {
            if (_isConnected)
                return;
 
            try
            {
                // 加上 PipeOptions.Asynchronous 可以异步接受服务器发送的数据,但是很影响性能
                _pipeClient = new NamedPipeClientStream(_serverName, _pipeName, PipeDirection.InOut);
 
                // 创建超时取消令牌
                using (var timeoutCts = new CancellationTokenSource(timeoutMs))
                {
                    _pipeClient.Connect(timeoutMs);
                    _pipeClient.ReadMode = PipeTransmissionMode.Message;
                    _isConnected = true;
 
                    // 触发连接成功事件
                    OnConnected?.Invoke(this, EventArgs.Empty);
 
                    // 开始接收数据
                    //_receiveThread = new Thread(ReceiveData);
                    //_receiveThread.Start();
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }
 
        private void ReceiveData()
        {
            try
            {
                while (_isConnected && !_cancellationTokenSource.Token.IsCancellationRequested)
                {
                    string message = _pipeClient.ReadMessage();
                    if (string.IsNullOrEmpty(message))
                        break;
                    // 触发数据接收事件
                    OnData?.Invoke(this, new PipeDataEventArgs("", message));
                }
            }
            finally
            {
                _isConnected = false;
                // 触发断开连接事件
                OnDisconnected?.Invoke(this, EventArgs.Empty);
            }
        }
 
        public bool SendMessage(string message, out string response, int timeoutMs = 5000)
        {
            response = null;
            if (!_isConnected)
                return false;
            try
            {
 
                _lock.EnterWriteLock();
                try
                {
                    _pipeClient.WriteMessage(message);
                }
                finally
                {
                    _lock.ExitWriteLock();
                }
                response = _pipeClient.ReadMessage();
                return true;
            }
            catch (Exception ex)
            {
                response = ex.Message;
                return false;
            }
        }
 
        public void Disconnect()
        {
            _isConnected = false;
            _cancellationTokenSource.Cancel();
            _receiveThread?.Join(1000); // 等待接收线程结束
        }
 
        public void Dispose()
        {
            if (!_isDisposed)
            {
                Disconnect();
                _pipeClient?.Dispose();
                _cancellationTokenSource.Dispose();
                _lock.Dispose();
                _isDisposed = true;
            }
        }
    }
}