Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Thick-Common
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
潘栩锋
Thick-Common
Commits
73a08e4b
Commit
73a08e4b
authored
Sep 02, 2023
by
潘栩锋
🚴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.修复 Dev7E 线程安全优化
2.修复 flyad2021B2,连接断开恢复优化
parent
8593d013
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
142 additions
and
402 deletions
+142
-402
Dev7E.cs
GeneralGommunication/Dev7E.cs
+21
-14
GComm_TcpClient.cs
GeneralGommunication/GComm_TcpClient.cs
+67
-373
IDev7E.cs
GeneralGommunication/IDev7E.cs
+1
-1
IModbusAsciiAsync.cs
GeneralGommunication/IModbusAsciiAsync.cs
+1
-1
ModbusAsciiAsync.cs
GeneralGommunication/ModbusAsciiAsync.cs
+1
-1
ModbusRTUAsync.cs
GeneralGommunication/ModbusRTUAsync.cs
+1
-1
Modbus_Transaction.cs
GeneralGommunication/Modbus_Transaction.cs
+4
-1
FlyAd2021B2.cs
Project.FLY.FlyADBase/FlyAd2021.B2/FlyAd2021B2.cs
+46
-10
No files found.
GeneralGommunication/Dev7E.cs
View file @
73a08e4b
...
...
@@ -43,9 +43,9 @@ namespace GeneralGommunication
/// <summary>
/// 有数据需要发送
/// </summary>
public
event
SendDataEventHander
SendMsgEvent
;
public
event
SendDataEventHandler
SendMsgEvent
;
public
event
TimeOutEventHandler
TimeOutEvent
;
...
...
@@ -125,6 +125,8 @@ namespace GeneralGommunication
{
//已经重试了3次,放弃
ResetMsg
();
//连接断开
TimeOutEvent
?.
Invoke
(
this
);
return
;
}
else
...
...
@@ -140,25 +142,30 @@ namespace GeneralGommunication
//IsConnected = true;
csm
.
IncRec
(
recBuf
.
Count
());
for
(
int
i
=
0
;
i
<
recBuf
.
Count
();
i
++)
List
<
byte
[
]>
packs
=
new
List
<
byte
[
]>
();
lock
(
currPack
)
{
if
(
recBuf
[
i
]
==
0x7e
)
for
(
int
i
=
0
;
i
<
recBuf
.
Count
();
i
++
)
{
//找到头了
//结束之前的包
if
(
currPack
.
Count
>
0
)
if
(
recBuf
[
i
]
==
0x7e
)
{
var
pack
=
currPack
.
ToArray
();
ParsePack
(
pack
);
currPack
.
Clear
();
csm
.
IncPack
(
1
);
//找到头了
//结束之前的包
if
(
currPack
.
Count
>
0
)
{
var
pack
=
currPack
.
ToArray
();
packs
.
Add
(
pack
);
currPack
.
Clear
();
csm
.
IncPack
(
1
);
}
}
currPack
.
Add
(
recBuf
[
i
]);
}
currPack
.
Add
(
recBuf
[
i
]);
}
//OnPoll_TimeOut();
for
(
int
i
=
0
;
i
<
packs
.
Count
();
i
++)
{
ParsePack
(
packs
[
i
]);
}
}
...
...
GeneralGommunication/GComm_TcpClient.cs
View file @
73a08e4b
...
...
@@ -10,354 +10,6 @@ using System.Threading.Tasks;
namespace
GeneralGommunication
{
//public class GComm_TcpClient : IGeneralComm
//{
// public Logger logger = NLog.LogManager.GetCurrentClassLogger();
// /// <summary>
// /// IP 地址 and 端口号
// /// </summary>
// public string Addr { get; set; }
// IPEndPoint RemoteEp => Misc.StringConverter.ToIPEndPoint(Addr);
// /// <summary>
// /// 是否异常
// /// </summary>
// public bool IsError => !string.IsNullOrEmpty(ErrMsg);
// /// <summary>
// /// 异常信息
// /// </summary>
// public string ErrMsg { get; private set; }
// /// <summary>
// /// 运行中
// /// </summary>
// public bool IsRunning { get; private set; }
// /// <summary>
// /// 连接成功
// /// </summary>
// public bool IsConnected { get; private set; }
// /// <summary>
// /// 接收task调用
// /// </summary>
// public event IGeneralCommDataReceivedHandler DataReceived;
// public event PropertyChangedEventHandler PropertyChanged;
// Socket sock;
// CancellationTokenSource cts_readTask;
// CancellationTokenSource cts_waitForSend;
// CancellationTokenSource cts_sendTask;
// public GComm_TcpClient()
// {
// }
// /// <summary>
// /// 开始
// /// </summary>
// public void Start()
// {
// if (IsRunning)
// return;
// IsRunning = true;
// cts_readTask = new CancellationTokenSource();
// Task.Factory.StartNew(OnTask, cts_readTask.Token);
// }
// /// <summary>
// /// 接收
// /// </summary>
// public void Stop()
// {
// if (!IsRunning)
// return;
// IsRunning = false;
// IsConnected = false;
// cts_readTask.Cancel();
// if (sock != null && sock.Connected)
// {
// sock.Close();
// sock = null;
// }
// }
// void OnTask()
// {
// while (!cts_readTask.IsCancellationRequested)
// {
// ConnectTask();
// if (IsConnected)
// {
// sendBuf.Clear();
// //启动发送task
// cts_sendTask = new CancellationTokenSource();
// var sendtask = Task.Factory.StartNew(SendTask, cts_sendTask.Token);
// //进入接收task
// ReceiveTask();
// //退出了,肯定连接断开了
// //需要等待 SendTask 也退出了
// cts_sendTask.Cancel();
// sendtask.Wait();
// if (sock != null)
// {
// sock.Close();
// }
// }
// //休息一会儿,在重连
// try
// {
// Task.Delay(2000, cts_readTask.Token).Wait();
// }
// catch (Exception e)
// {
// //被打断了
// break;
// }
// }
// IsConnected = false;
// }
// /// <summary>
// /// 连接任务
// /// </summary>
// void ConnectTask()
// {
// sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// sock.Blocking = true;
// //1秒内,需要收到信息
// sock.ReceiveTimeout = 1000;
// //1秒内,必须发送完
// sock.SendTimeout = 1000;
// while (!cts_readTask.IsCancellationRequested)
// {
// try
// {
// sock.Connect(RemoteEp);
// IsConnected = true;
// ErrMsg = null;
// return;
// }
// catch (SocketException e)
// {
// //连接出错
// //等待重试
// ErrMsg = e.Message;
// }
// try
// {
// Task.Delay(2000, cts_readTask.Token).Wait();
// }
// catch (Exception e)
// {
// //被打断
// return;
// }
// }
// }
// /// <summary>
// /// 接收任务
// /// </summary>
// void ReceiveTask()
// {
// byte[] buf = new byte[sock.ReceiveBufferSize];
// while (!cts_readTask.IsCancellationRequested)
// {
// int len;
// try
// {
// len = sock.Receive(buf);
// if (len == 0)
// {
// continue;//没收到数据,继续等
// }
// }
// catch (SocketException e)
// {
// if (e.SocketErrorCode == SocketError.TimedOut)
// continue;//超时而已
// else if ((e.SocketErrorCode == SocketError.ConnectionAborted)
// || (e.SocketErrorCode == SocketError.ConnectionRefused)
// || (e.SocketErrorCode == SocketError.ConnectionReset))
// {
// IsConnected = false;
// return;
// }
// //Console.WriteLine($"ReceiveTask() {e}");
// //肯定断开连接了
// IsConnected = false;
// break;
// }
// logger.Debug($"ReceiveTask len={len}");
// DataReceived?.Invoke(this, buf.Take(len).ToArray());
// }
// IsConnected = false;
// }
// /// <summary>
// /// 发送任务
// /// </summary>
// void SendTask()
// {
// while (!cts_sendTask.IsCancellationRequested)
// {
// CancellationTokenSource cts3;
// while (true)
// {
// byte[] buffer;
// lock (sendBuf)
// {
// if (sendBuf.Count <= 0)
// break;
// buffer = sendBuf.ToArray();
// }
// int slen;
// try
// {
// slen = sock.Send(buffer);
// logger.Debug($"SendTask len={slen}");
// }
// catch (Exception e)
// {
// //连接断开了
// IsConnected = false;
// break;
// }
// if (slen <= 0)
// {
// //连接断开了
// IsConnected = false;
// break;
// }
// else
// {
// lock (sendBuf)
// {
// if (slen == sendBuf.Count())
// {
// sendBuf.Clear();
// break;
// }
// else
// {
// sendBuf.RemoveRange(0, slen);
// }
// }
// }
// }
// //重新等 下次被呼醒
// lock (sendBuf)
// {
// // 呼醒 发送task
// if (cts_waitForSend == null)
// {
// cts_waitForSend = new CancellationTokenSource();
// }
// //cts_waitForSend 与 cts_sendTask 合体, 任意一个都会呼醒 delay
// cts3 = CancellationTokenSource.CreateLinkedTokenSource(cts_waitForSend.Token, cts_sendTask.Token);
// }
// try
// {
// Task.Delay(-1, cts3.Token).Wait();
// }
// catch (Exception e)
// {
// //被打断, 有数据需要发送
// }
// cts_waitForSend = null;
// }
// }
// /// <summary>
// /// 无限大,发送缓存
// /// </summary>
// List<byte> sendBuf = new List<byte>();
// ///// <summary>
// ///// 发送数据
// ///// </summary>
// ///// <param name="buf"></param>
// //public void Write(IEnumerable<byte> buf)
// //{
// // if (!IsConnected)
// // return;
// // lock (sendBuf)
// // {
// // //放入,发送缓存区
// // sendBuf.AddRange(buf);
// // //呼醒 发送task
// // if (cts_waitForSend == null)
// // {
// // cts_waitForSend = new CancellationTokenSource();
// // }
// // cts_waitForSend.Cancel();
// // }
// //}
// /// <summary>
// /// 发送数据
// /// </summary>
// /// <param name="buf"></param>
// public void Write(IEnumerable<byte> buf)
// {
// if (!IsConnected)
// return;
// int slen;
// try
// {
// slen = sock.Send(buf.ToArray());
// logger.Debug($"SendTask len={slen}");
// }
// catch (Exception e)
// {
// //连接断开了
// IsConnected = false;
// return;
// }
// if (slen <= 0)
// {
// //连接断开了
// IsConnected = false;
// return;
// }
// }
// /// <summary>
// /// 清空输入缓存
// /// </summary>
// public void DiscardInBuffer()
// {
// //TODO
// }
//}
public
class
GComm_TcpClient
:
IGeneralComm
{
public
Logger
logger
;
// = NLog.LogManager.GetCurrentClassLogger();
...
...
@@ -399,6 +51,11 @@ namespace GeneralGommunication
Socket
sock
;
CancellationTokenSource
cts_readTask
;
/// <summary>
/// sock 的线程锁
/// </summary>
object
sock_lock
=
new
object
();
Task
task
=
null
;
public
GComm_TcpClient
()
{
...
...
@@ -412,9 +69,21 @@ namespace GeneralGommunication
if
(
IsRunning
)
return
;
IsRunning
=
true
;
cts_readTask
=
new
CancellationTokenSource
();
Task
.
Factory
.
StartNew
(
OnTask
,
cts_readTask
.
Token
);
if
(
task
==
null
||
task
.
IsCompleted
)
{
//线程已经完成, 创建个新的
cts_readTask
=
new
CancellationTokenSource
();
task
=
Task
.
Factory
.
StartNew
(
OnTask
,
cts_readTask
.
Token
);
}
else
{
//线程还没结束,等待结束后,再创建新的
task
.
Wait
();
cts_readTask
=
new
CancellationTokenSource
();
task
=
Task
.
Factory
.
StartNew
(
OnTask
,
cts_readTask
.
Token
);
}
}
/// <summary>
...
...
@@ -427,13 +96,37 @@ namespace GeneralGommunication
IsRunning
=
false
;
IsConnected
=
false
;
cts_readTask
.
Cancel
();
if
(
sock
!=
null
&&
sock
.
Connected
)
closeSock
();
}
/// <summary>
/// 关闭sock,打断接收,发送中的等待,非OnTask调用
/// </summary>
void
closeSock
()
{
lock
(
sock_lock
)
{
sock
.
Close
();
sock
=
null
;
if
(
sock
!=
null
&&
sock
.
Connected
)
{
sock
.
Close
();
}
}
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
closeSock"
);
}
/// <summary>
/// 释放sock, 只能在OnTask中调用
/// </summary>
void
disposeSock
()
{
lock
(
sock_lock
)
//lock住,防止外部线程在 sock==null 时,调用sock.Close()
{
if
(
sock
!=
null
)
{
sock
.
Close
();
sock
=
null
;
}
}
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
disposeSock"
);
}
void
OnTask
()
{
while
(!
cts_readTask
.
IsCancellationRequested
)
...
...
@@ -446,14 +139,10 @@ namespace GeneralGommunication
ReceiveTask
();
//退出了,肯定连接断开了
if
(
sock
!=
null
)
{
sock
.
Close
();
}
disposeSock
();
}
//休息一会儿,
在
重连
//休息一会儿,
再
重连
try
{
Task
.
Delay
(
2000
,
cts_readTask
.
Token
).
Wait
();
...
...
@@ -464,7 +153,7 @@ namespace GeneralGommunication
break
;
}
}
disposeSock
();
IsConnected
=
false
;
}
...
...
@@ -473,12 +162,11 @@ namespace GeneralGommunication
/// </summary>
void
ConnectTask
()
{
while
(!
cts_readTask
.
IsCancellationRequested
)
{
try
{
//sock 的 创建,销毁,只能在 这个线程操作
sock
=
new
Socket
(
AddressFamily
.
InterNetwork
,
SocketType
.
Stream
,
ProtocolType
.
Tcp
);
sock
.
Blocking
=
true
;
...
...
@@ -494,22 +182,26 @@ namespace GeneralGommunication
if
(
sucess
)
{
sock
.
EndConnect
(
result
);
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
connect success"
);
IsConnected
=
true
;
ErrMsg
=
null
;
return
;
}
else
{
sock
.
Close
();
disposeSock
();
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
connect timeout"
);
ErrMsg
=
"连接超时"
;
}
}
catch
(
Exception
e
)
{
disposeSock
();
//连接出错
//等待重试
ErrMsg
=
e
.
Message
;
}
try
{
Task
.
Delay
(
2000
,
cts_readTask
.
Token
).
Wait
();
...
...
@@ -543,24 +235,26 @@ namespace GeneralGommunication
{
if
(
e
.
SocketErrorCode
==
SocketError
.
TimedOut
)
continue
;
//超时而已
else
if
((
e
.
SocketErrorCode
==
SocketError
.
ConnectionAborted
)
||
(
e
.
SocketErrorCode
==
SocketError
.
ConnectionRefused
)
||
(
e
.
SocketErrorCode
==
SocketError
.
ConnectionReset
))
{
IsConnected
=
false
;
ErrMsg
=
e
.
Message
;
return
;
}
//
else if ((e.SocketErrorCode == SocketError.ConnectionAborted)
//
|| (e.SocketErrorCode == SocketError.ConnectionRefused)
//
|| (e.SocketErrorCode == SocketError.ConnectionReset))
//
{
//
IsConnected = false;
//
ErrMsg = e.Message;
//
return;
//
}
//Console.WriteLine($"ReceiveTask() {e}");
//肯定断开连接了
IsConnected
=
false
;
ErrMsg
=
e
.
Message
;
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
ReceiveTask end for (Exception
{
e
.
SocketErrorCode
}
)"
);
return
;
}
logger
?.
Debug
(
$"tcp R len=
{
len
}
"
);
DataReceived
?.
Invoke
(
this
,
buf
.
Take
(
len
).
ToArray
());
}
Console
.
WriteLine
(
$"
{
DateTime
.
Now
}
ReceiveTask end for (cts_readTask.IsCancellationRequested == true)"
);
IsConnected
=
false
;
}
...
...
GeneralGommunication/IDev7E.cs
View file @
73a08e4b
...
...
@@ -28,7 +28,7 @@ namespace GeneralGommunication
/// <summary>
/// 有数据需要发送
/// </summary>
event
SendDataEventHander
SendMsgEvent
;
event
SendDataEventHand
l
er
SendMsgEvent
;
#
region
模块运行接口
...
...
GeneralGommunication/IModbusAsciiAsync.cs
View file @
73a08e4b
...
...
@@ -21,7 +21,7 @@ namespace GeneralGommunication
/// <summary>
/// 有数据需要发送
/// </summary>
event
SendDataEventHander
SendMsgEvent
;
event
SendDataEventHand
l
er
SendMsgEvent
;
/// <summary>
/// 设备连接状态改变
...
...
GeneralGommunication/ModbusAsciiAsync.cs
View file @
73a08e4b
...
...
@@ -37,7 +37,7 @@ namespace GeneralGommunication
/// <summary>
/// 有数据需要发送
/// </summary>
public
event
SendDataEventHander
SendMsgEvent
;
public
event
SendDataEventHand
l
er
SendMsgEvent
;
public
event
DeviceConnectEventHander
DeviceConnectEvent
;
...
...
GeneralGommunication/ModbusRTUAsync.cs
View file @
73a08e4b
...
...
@@ -36,7 +36,7 @@ namespace GeneralGommunication
/// <summary>
/// 有数据需要发送
/// </summary>
public
event
SendDataEventHander
SendMsgEvent
;
public
event
SendDataEventHand
l
er
SendMsgEvent
;
/// <summary>
/// 对于全部 有返回的函数调用,都使用Dispatcher,使线程同步
...
...
GeneralGommunication/Modbus_Transaction.cs
View file @
73a08e4b
...
...
@@ -101,5 +101,8 @@ namespace GeneralGommunication
public
string
errMsg
;
}
public
delegate
void
SendDataEventHander
(
object
sender
,
byte
[]
data
);
public
delegate
void
SendDataEventHandler
(
object
sender
,
byte
[]
data
);
public
delegate
void
TimeOutEventHandler
(
object
sender
);
}
Project.FLY.FlyADBase/FlyAd2021.B2/FlyAd2021B2.cs
View file @
73a08e4b
...
...
@@ -10,6 +10,7 @@ using System;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.ComponentModel
;
using
System.Diagnostics
;
using
System.IO
;
using
System.Linq
;
...
...
@@ -276,6 +277,10 @@ namespace FlyADBase
IsReadyContext
isReadyContext
=
new
IsReadyContext
();
SysTickContext
sysTickContext
=
new
SysTickContext
();
CalSpeed
calSpeed
=
new
CalSpeed
();
/// <summary>
/// 检查推送周期 10ms 有一个。 1秒内都没收到,应该断开了, 重连
/// </summary>
Stopwatch
stopwatch_pushIntervalCheck
=
new
Stopwatch
();
public
FlyAd2021B2Core
Core
=>
core
;
...
...
@@ -334,6 +339,9 @@ namespace FlyADBase
core
.
PushDataEvent
+=
(
sender
,
e
)
=>
{
//喂狗
stopwatch_pushIntervalCheck
.
Restart
();
//这个线程非主线程, 数据接收完,应该快速返回。
//事件触发,都放在主线程操作。
//要有线程锁!!!!!
...
...
@@ -434,6 +442,34 @@ namespace FlyADBase
}
},
TimeSpan
.
FromSeconds
(
1
));
PollModule
.
Current
.
Poll_Config
(
onPoll_CheckPush
);
}
/// <summary>
/// 推送检查 ,没推送,就是连接断开
/// </summary>
private
void
onPoll_CheckPush
()
{
if
(!
IsConnected
)
{
if
(
stopwatch_pushIntervalCheck
.
IsRunning
)
stopwatch_pushIntervalCheck
.
Stop
();
return
;
}
if
(!
stopwatch_pushIntervalCheck
.
IsRunning
)
{
stopwatch_pushIntervalCheck
.
Restart
();
}
else
{
if
(
stopwatch_pushIntervalCheck
.
ElapsedMilliseconds
>
1000
)
{
//1000ms 都没收到推送,连接断开
ReConnect
();
}
}
}
void
GetRunResult
()
...
...
@@ -608,6 +644,8 @@ namespace FlyADBase
}
void
_core_PushDataEvent
(
PushDataEventArgs
e
)
{
Now
=
sysTickContext
.
ToDateTime
(
e
.
SysTick
);
if
(
e
.
ENC1
!=
null
)
...
...
@@ -649,16 +687,6 @@ namespace FlyADBase
advPushData
(
Now
,
e
.
AD
,
e
.
AD2
);
}
private
void
Core_PushDataEvent
(
object
sender
,
PushDataEventArgs
_e
)
{
//这个线程非主线程, 数据接收完,应该快速返回。
//事件触发,都放在主线程操作。
//要有线程锁!!!!!
lock
(
pushEventArgs
)
{
pushEventArgs
.
Add
(
_e
);
}
}
/// <summary>
/// 连接后初始化
...
...
@@ -826,12 +854,20 @@ namespace FlyADBase
}
comm
.
DataReceived
+=
Comm_DataReceived
;
comm
.
PropertyChanged
+=
Comm_PropertyChanged
;
core
.
TimeOutEvent
+=
Core_TimeOutEvent
;
core
.
ResetMsg
();
}
private
void
Core_TimeOutEvent
(
object
sender
)
{
//回复超时,可能连接断开, 重新连接
ReConnect
();
}
void
disposeComm
()
{
comm
.
DataReceived
-=
Comm_DataReceived
;
comm
.
PropertyChanged
-=
Comm_PropertyChanged
;
core
.
TimeOutEvent
-=
Core_TimeOutEvent
;
core
.
ResetMsg
();
}
private
void
Comm_DataReceived
(
IGeneralComm
sender
,
byte
[]
msg
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment