From 249c6fe36cedc58727348abe3a9a64a40bb5bf88 Mon Sep 17 00:00:00 2001 From: "parallelbgls@outlook.com" Date: Tue, 14 Apr 2015 09:57:59 +0800 Subject: [PATCH] 2015-04-14 update 1 Add Task Manager --- Modbus.Net/ModBus.Net/BaseConnector.cs | 4 + Modbus.Net/ModBus.Net/BaseMachine.cs | 54 +++ Modbus.Net/ModBus.Net/BaseProtocal.cs | 10 +- Modbus.Net/ModBus.Net/BaseUtility.cs | 33 +- Modbus.Net/ModBus.Net/ComConnector.cs | 83 +++-- Modbus.Net/ModBus.Net/ComProtocalLinker.cs | 2 +- Modbus.Net/ModBus.Net/ModBus.Net.csproj | 3 + Modbus.Net/ModBus.Net/ModbusProtocal.cs | 5 - .../ModBus.Net/ModbusRtuProtocalLinker.cs | 1 + .../ModBus.Net/ModbusTcpProtocalLinker.cs | 1 + Modbus.Net/ModBus.Net/ModbusUtility.cs | 4 +- Modbus.Net/ModBus.Net/ProtocalLinker.cs | 19 +- Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs | 5 - .../ModBus.Net/SimenseTcpProtocalLinker.cs | 1 + Modbus.Net/ModBus.Net/SimenseUtility.cs | 7 +- Modbus.Net/ModBus.Net/TaskManager.cs | 313 ++++++++++++++++++ Modbus.Net/ModBus.Net/TcpConnector.cs | 20 +- Modbus.Net/ModBus.Net/TcpProtocalLinker.cs | 2 +- Modbus.Net/Modbus.Net-vs2013.sln | 8 +- Modbus.Net/NA200H.UI.Console/Program.cs | 4 +- Modbus.Net/NA200H.UI.WPF/MainWindow.xaml.cs | 2 +- 21 files changed, 516 insertions(+), 65 deletions(-) create mode 100644 Modbus.Net/ModBus.Net/BaseMachine.cs create mode 100644 Modbus.Net/ModBus.Net/TaskManager.cs diff --git a/Modbus.Net/ModBus.Net/BaseConnector.cs b/Modbus.Net/ModBus.Net/BaseConnector.cs index 4f24c16..0924822 100644 --- a/Modbus.Net/ModBus.Net/BaseConnector.cs +++ b/Modbus.Net/ModBus.Net/BaseConnector.cs @@ -8,6 +8,10 @@ namespace ModBus.Net { public abstract class BaseConnector { + public abstract string ConnectionToken { get; } + /// + /// 是否处于连接状态 + /// public abstract bool IsConnected { get; } /// /// 连接PLC diff --git a/Modbus.Net/ModBus.Net/BaseMachine.cs b/Modbus.Net/ModBus.Net/BaseMachine.cs new file mode 100644 index 0000000..d124ed1 --- /dev/null +++ b/Modbus.Net/ModBus.Net/BaseMachine.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ModBus.Net +{ + public abstract class BaseMachine + { + public IEnumerable GetAddresses { get; set; } + + public bool KeepConnect { get; set; } + + public BaseUtility BaseUtility { get; protected set; } + + protected BaseMachine(IEnumerable getAddresses) : this(getAddresses, false) + { + } + + protected BaseMachine(IEnumerable getAddresses, bool keepConnect) + { + GetAddresses = getAddresses; + KeepConnect = keepConnect; + } + + public IEnumerable> GetDatas() + { + List ans = new List(); + if (!BaseUtility.IsConnected) + { + BaseUtility.Connect(); + } + foreach (var getAddress in GetAddresses) + { + ans.Add(BaseUtility.GetDatas(2, 0, getAddress.StartAddress, new KeyValuePair(getAddress.DataType, getAddress.GetCount))); + } + if (!KeepConnect) + { + BaseUtility.DisConnect(); + } + return ans; + } + } + + public struct CommunicationUnit + { + public string StartAddress { get; set; } + public int GetCount { get; set; } + public Type DataType { get; set; } + } +} diff --git a/Modbus.Net/ModBus.Net/BaseProtocal.cs b/Modbus.Net/ModBus.Net/BaseProtocal.cs index 940c413..d794615 100644 --- a/Modbus.Net/ModBus.Net/BaseProtocal.cs +++ b/Modbus.Net/ModBus.Net/BaseProtocal.cs @@ -93,7 +93,13 @@ namespace ModBus.Net /// 协议连接断开 /// /// - public abstract bool Disconnect(); - + public virtual bool Disconnect() + { + if (ProtocalLinker != null) + { + return ProtocalLinker.Disconnect(); + } + return false; + } } } \ No newline at end of file diff --git a/Modbus.Net/ModBus.Net/BaseUtility.cs b/Modbus.Net/ModBus.Net/BaseUtility.cs index 36e743f..297c368 100644 --- a/Modbus.Net/ModBus.Net/BaseUtility.cs +++ b/Modbus.Net/ModBus.Net/BaseUtility.cs @@ -13,7 +13,21 @@ namespace ModBus.Net /// 协议收发主体 /// protected BaseProtocal Wrapper; - public virtual string ConnectionString { get; set; } + protected virtual string ConnectionString { get; set; } + + public bool IsConnected + { + get + { + if (Wrapper == null || Wrapper.ProtocalLinker == null) return false; + return Wrapper.ProtocalLinker.IsConnected; + } + } + + public string ConnectionToken + { + get { return Wrapper.ProtocalLinker.ConnectionToken; } + } public AddressTranslator AddressTranslator { get; set; } @@ -45,6 +59,13 @@ namespace ModBus.Net return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); } + public virtual T[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, + int getByteCount) + { + var getBytes = GetDatas(belongAddress, masterAddress, startAddress, new KeyValuePair(typeof(T), getByteCount)); + return ValueHelper.Instance.ObjectArrayToDestinationArray(getBytes); + } + public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, IEnumerable> getTypeAndCountList) { @@ -82,5 +103,15 @@ namespace ModBus.Net /// 设置PLC时间 /// 设置是否成功 public abstract bool SetTime(byte belongAddress, DateTime setTime); + + public bool Connect() + { + return Wrapper.Connect(); + } + + public bool DisConnect() + { + return Wrapper.Disconnect(); + } } } diff --git a/Modbus.Net/ModBus.Net/ComConnector.cs b/Modbus.Net/ModBus.Net/ComConnector.cs index b8fec78..4398daf 100644 --- a/Modbus.Net/ModBus.Net/ComConnector.cs +++ b/Modbus.Net/ModBus.Net/ComConnector.cs @@ -10,38 +10,49 @@ namespace ModBus.Net { public class ComConnector : BaseConnector, IDisposable { - private SerialPort serialPort1 = new SerialPort(); + public override string ConnectionToken { get { return _com; } + } - public delegate byte[] getDate(byte[] bts); + private SerialPort _serialPort1; - private getDate mygetDate; - private string com; + public delegate byte[] GetDate(byte[] bts); - public ComConnector(string com) + private GetDate mygetDate; + private readonly string _com; + + public ComConnector(string com, int timeoutTime) { - this.com = com; - serialPort1.PortName = com; //端口号 - serialPort1.BaudRate = 9600; //比特率 - serialPort1.Parity = Parity.None; //奇偶校验 - serialPort1.StopBits = StopBits.One; //停止位 - serialPort1.DataBits = 8; - serialPort1.ReadTimeout = 1000; //读超时,即在1000内未读到数据就引起超时异常 + this._com = com; + _serialPort1 = new SerialPort + { + PortName = com, + BaudRate = 9600, + Parity = Parity.None, + StopBits = StopBits.One, + DataBits = 8, + ReadTimeout = timeoutTime, + }; + //端口号 + //比特率 + //奇偶校验 + //停止位 + //读超时,即在1000内未读到数据就引起超时异常 } #region 发送接收数据 public override bool IsConnected { - get { return serialPort1 != null && serialPort1.IsOpen; } + get { return _serialPort1 != null && _serialPort1.IsOpen; } } public override bool Connect() { - if (serialPort1 != null) + if (_serialPort1 != null) { try { - serialPort1.Open(); + _serialPort1.Open(); return true; } catch @@ -59,11 +70,11 @@ namespace ModBus.Net public override bool Disconnect() { - if (serialPort1 != null) + if (_serialPort1 != null) { try { - serialPort1.Close(); + _serialPort1.Close(); return true; } catch @@ -91,16 +102,16 @@ namespace ModBus.Net { try { - if (!serialPort1.IsOpen) + if (!_serialPort1.IsOpen) { - serialPort1.Open(); + _serialPort1.Open(); } - serialPort1.Write(sendbytes, 0, sendbytes.Length); + _serialPort1.Write(sendbytes, 0, sendbytes.Length); return ReadMsg(); } catch { - serialPort1.Close(); + _serialPort1.Close(); return null; } } @@ -114,7 +125,7 @@ namespace ModBus.Net { try { - serialPort1.Write(sendbytes, 0, sendbytes.Length); + _serialPort1.Write(sendbytes, 0, sendbytes.Length); return true; } catch (Exception) @@ -139,22 +150,22 @@ namespace ModBus.Net { try { - if (!serialPort1.IsOpen) + if (!_serialPort1.IsOpen) { - serialPort1.Open(); + _serialPort1.Open(); } byte[] data = new byte[200]; Thread.Sleep(100); - int i = serialPort1.Read(data, 0, serialPort1.BytesToRead); + int i = _serialPort1.Read(data, 0, _serialPort1.BytesToRead); byte[] returndata = new byte[i]; Array.Copy(data, 0, returndata, 0, i); - serialPort1.Close(); + _serialPort1.Close(); return returndata; } catch (Exception) { - serialPort1.Close(); + _serialPort1.Close(); return null; } } @@ -176,15 +187,15 @@ namespace ModBus.Net Array.Clear(readBuf, 0, readBuf.Length); int nReadLen, nBytelen; - if (serialPort1.IsOpen == false) + if (_serialPort1.IsOpen == false) return -1; nBytelen = 0; - serialPort1.ReadTimeout = HowTime; + _serialPort1.ReadTimeout = HowTime; try { - readBuf[nBytelen] = (byte) serialPort1.ReadByte(); + readBuf[nBytelen] = (byte) _serialPort1.ReadByte(); byte[] bTmp = new byte[1023]; Array.Clear(bTmp, 0, bTmp.Length); @@ -225,16 +236,16 @@ namespace ModBus.Net sbyte nBytelen; //long nByteRead; - if (serialPort1.IsOpen == false) + if (_serialPort1.IsOpen == false) return 0; nBytelen = 0; - serialPort1.ReadTimeout = ByteTime; + _serialPort1.ReadTimeout = ByteTime; while (nBytelen < (ReadRoom - 1)) { try { - ReadBuf[nBytelen] = (byte) serialPort1.ReadByte(); + ReadBuf[nBytelen] = (byte) _serialPort1.ReadByte(); nBytelen++; // add one } catch (Exception ex) @@ -330,10 +341,10 @@ namespace ModBus.Net public void Dispose() { - if (serialPort1 != null) + if (_serialPort1 != null) { - serialPort1.Close(); - serialPort1.Dispose(); + _serialPort1.Close(); + _serialPort1.Dispose(); } } } diff --git a/Modbus.Net/ModBus.Net/ComProtocalLinker.cs b/Modbus.Net/ModBus.Net/ComProtocalLinker.cs index 012d74b..ffcbdf2 100644 --- a/Modbus.Net/ModBus.Net/ComProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ComProtocalLinker.cs @@ -16,7 +16,7 @@ namespace ModBus.Net protected ComProtocalLinker(string com) { //初始化连对象 - _baseConnector = new ComConnector(com); + _baseConnector = new ComConnector(com, 30000); } } } diff --git a/Modbus.Net/ModBus.Net/ModBus.Net.csproj b/Modbus.Net/ModBus.Net/ModBus.Net.csproj index 0af31ab..c878027 100644 --- a/Modbus.Net/ModBus.Net/ModBus.Net.csproj +++ b/Modbus.Net/ModBus.Net/ModBus.Net.csproj @@ -51,7 +51,9 @@ + + @@ -72,6 +74,7 @@ + diff --git a/Modbus.Net/ModBus.Net/ModbusProtocal.cs b/Modbus.Net/ModBus.Net/ModbusProtocal.cs index 23a453c..4febb7c 100644 --- a/Modbus.Net/ModBus.Net/ModbusProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusProtocal.cs @@ -45,11 +45,6 @@ namespace ModBus.Net { return ProtocalLinker.Connect(); } - - public override bool Disconnect() - { - return ProtocalLinker.Disconnect(); - } } #region 读PLC数据 diff --git a/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs b/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs index 44a998f..8134387 100644 --- a/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs @@ -10,6 +10,7 @@ namespace ModBus.Net { public override bool CheckRight(byte[] content) { + if (!base.CheckRight(content)) return false; //CRC校验失败 if (!Crc16.GetInstance().CrcEfficacy(content)) { diff --git a/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs b/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs index f8f3d99..d738310 100644 --- a/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs @@ -10,6 +10,7 @@ namespace ModBus.Net { public override bool CheckRight(byte[] content) { + if (!base.CheckRight(content)) return false; //长度校验失败 if (content[5] != content.Length - 6) { diff --git a/Modbus.Net/ModBus.Net/ModbusUtility.cs b/Modbus.Net/ModBus.Net/ModbusUtility.cs index 09cc448..ccf3e6e 100644 --- a/Modbus.Net/ModBus.Net/ModbusUtility.cs +++ b/Modbus.Net/ModBus.Net/ModbusUtility.cs @@ -54,12 +54,14 @@ namespace ModBus.Net { ConnectionString = null; ModbusType = (ModbusType)connectionType; + AddressTranslator = new AddressTranslatorBase(); } public ModbusUtility(ModbusType connectionType, string connectionString) { ConnectionString = connectionString; - ModbusType = connectionType; + ModbusType = connectionType; + AddressTranslator = new AddressTranslatorBase(); } public override void SetConnectionType(int connectionType) diff --git a/Modbus.Net/ModBus.Net/ProtocalLinker.cs b/Modbus.Net/ModBus.Net/ProtocalLinker.cs index 46fcf4d..13e6340 100644 --- a/Modbus.Net/ModBus.Net/ProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ProtocalLinker.cs @@ -10,6 +10,11 @@ namespace ModBus.Net { protected BaseConnector _baseConnector; + public string ConnectionToken + { + get { return _baseConnector.ConnectionToken; } + } + public bool IsConnected { get { return _baseConnector.IsConnected; } @@ -57,7 +62,15 @@ namespace ModBus.Net /// /// 接收协议的内容 /// 协议是否是正确的 - public abstract bool CheckRight(byte[] content); + public virtual bool CheckRight(byte[] content) + { + if (content == null) + { + Disconnect(); + return false; + } + return true; + } /// /// 协议内容扩展,发送时根据需要扩展 @@ -68,7 +81,7 @@ namespace ModBus.Net { //自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。 ProtocalLinkerBytesExtend bytesExtend = - Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as + Assembly.Load(this.GetType().Assembly.GetName().Name).CreateInstance(this.GetType().FullName + "BytesExtend") as ProtocalLinkerBytesExtend; return bytesExtend.BytesExtend(content); } @@ -82,7 +95,7 @@ namespace ModBus.Net { //自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。 ProtocalLinkerBytesExtend bytesExtend = - Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as + Assembly.Load(this.GetType().Assembly.GetName().Name).CreateInstance(this.GetType().FullName + "BytesExtend") as ProtocalLinkerBytesExtend; return bytesExtend.BytesDecact(content); } diff --git a/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs b/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs index fc1d0cb..c6aed69 100644 --- a/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs +++ b/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs @@ -77,10 +77,5 @@ namespace ModBus.Net } return false; } - - public override bool Disconnect() - { - return ProtocalLinker.Disconnect(); - } } } diff --git a/Modbus.Net/ModBus.Net/SimenseTcpProtocalLinker.cs b/Modbus.Net/ModBus.Net/SimenseTcpProtocalLinker.cs index a7a395f..6315f06 100644 --- a/Modbus.Net/ModBus.Net/SimenseTcpProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/SimenseTcpProtocalLinker.cs @@ -9,6 +9,7 @@ namespace ModBus.Net { public override bool CheckRight(byte[] content) { + if (!base.CheckRight(content)) return false; switch (content[5]) { case 0xd0: diff --git a/Modbus.Net/ModBus.Net/SimenseUtility.cs b/Modbus.Net/ModBus.Net/SimenseUtility.cs index 4207319..411c31c 100644 --- a/Modbus.Net/ModBus.Net/SimenseUtility.cs +++ b/Modbus.Net/ModBus.Net/SimenseUtility.cs @@ -17,7 +17,7 @@ namespace ModBus.Net { private string _connectionString; - public override string ConnectionString + protected override string ConnectionString { get { return _connectionString; } set @@ -28,8 +28,8 @@ namespace ModBus.Net case "200": { _tdpuSize = 0x09; - _taspSrc = 0x4d57; - _tsapDst = 0x4d57; + _taspSrc = 0x1001; + _tsapDst = 0x1000; _maxCalling = 0x0001; _maxCalled = 0x0001; _maxPdu = 0x03c0; @@ -92,6 +92,7 @@ namespace ModBus.Net { ConnectionString = connectionString; ConnectionType = connectionType; + AddressTranslator = new AddressTranslatorSimense(); } public override void SetConnectionType(int connectionType) diff --git a/Modbus.Net/ModBus.Net/TaskManager.cs b/Modbus.Net/ModBus.Net/TaskManager.cs new file mode 100644 index 0000000..da33e15 --- /dev/null +++ b/Modbus.Net/ModBus.Net/TaskManager.cs @@ -0,0 +1,313 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Timer = System.Timers.Timer; +using ModBus.Net; + +namespace ModBus.Net +{ + public static class TimeRestore + { + public static int Restore = 0; + } + + public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler + { + /// + /// Whether the current thread is processing work items. + /// + [ThreadStatic] + private static bool _currentThreadIsProcessingItems; + /// + /// The list of tasks to be executed. + /// + private readonly LinkedList _tasks = new LinkedList(); // protected by lock(_tasks) + /// + /// The maximum concurrency level allowed by this scheduler. + /// + private readonly int _maxDegreeOfParallelism; + /// + /// Whether the scheduler is currently processing work items. + /// + private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks) + + /// + /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the + /// specified degree of parallelism. + /// + /// + /// The maximum degree of parallelism provided by this scheduler. + /// + public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) + { + if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); + _maxDegreeOfParallelism = maxDegreeOfParallelism; + } + + /// + /// Queues a task to the scheduler. + /// + /// + /// The task to be queued. + /// + protected sealed override void QueueTask(Task task) + { + // Add the task to the list of tasks to be processed. If there aren't enough + // delegates currently queued or running to process tasks, schedule another. + lock (_tasks) + { + _tasks.AddLast(task); + if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism) + { + ++_delegatesQueuedOrRunning; + NotifyThreadPoolOfPendingWork(); + } + } + } + + /// + /// Informs the ThreadPool that there's work to be executed for this scheduler. + /// + private void NotifyThreadPoolOfPendingWork() + { + ThreadPool.UnsafeQueueUserWorkItem(_ => + { + // Note that the current thread is now processing work items. + // This is necessary to enable inlining of tasks into this thread. + _currentThreadIsProcessingItems = true; + try + { + // Process all available items in the queue. + while (true) + { + Task item; + lock (_tasks) + { + // When there are no more items to be processed, + // note that we're done processing, and get out. + if (_tasks.Count == 0) + { + --_delegatesQueuedOrRunning; + break; + } + + // Get the next item from the queue + item = _tasks.First.Value; + _tasks.RemoveFirst(); + } + + // Execute the task we pulled out of the queue + base.TryExecuteTask(item); + } + } + // We're done processing items on the current thread + finally { _currentThreadIsProcessingItems = false; } + }, null); + } + + /// Attempts to execute the specified task on the current thread. + /// The task to be executed. + /// + /// Whether the task could be executed on the current thread. + protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) + { + // If this thread isn't already processing a task, we don't support inlining + if (!_currentThreadIsProcessingItems) return false; + + // If the task was previously queued, remove it from the queue + if (taskWasPreviouslyQueued) TryDequeue(task); + + // Try to run the task. + return base.TryExecuteTask(task); + } + + /// + /// Attempts to remove a previously scheduled task from the scheduler. + /// + /// + /// The task to be removed. + /// + /// + /// Whether the task could be found and removed. + /// + protected sealed override bool TryDequeue(Task task) + { + lock (_tasks) return _tasks.Remove(task); + } + + /// + /// Gets the maximum concurrency level supported by this scheduler. + /// + public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } + + /// + /// Gets an enumerable of the tasks currently scheduled on this scheduler. + /// + /// + /// An enumerable of the tasks currently scheduled. + /// + protected sealed override IEnumerable GetScheduledTasks() + { + bool lockTaken = false; + try + { + Monitor.TryEnter(_tasks, ref lockTaken); + if (lockTaken) return _tasks.ToArray(); + else throw new NotSupportedException(); + } + finally + { + if (lockTaken) Monitor.Exit(_tasks); + } + } + } + + public class BaseMachineEqualityComparer : IEqualityComparer + { + public bool Equals(BaseMachine x, BaseMachine y) + { + return x.BaseUtility.ConnectionToken == y.BaseUtility.ConnectionToken; + } + + public int GetHashCode(BaseMachine obj) + { + return obj.GetHashCode(); + } + } + + public class TaskManager + { + private HashSet _machines; + private TaskFactory>> _tasks; + private TaskScheduler _scheduler; + private CancellationTokenSource _cts; + private Timer _timer; + + private bool _keepConnect; + public bool KeepConnect { get { return _keepConnect; } set { TaskStop(); _keepConnect = value; + foreach (var machine in _machines) + { + machine.KeepConnect = _keepConnect; + } + } } + + public delegate void ReturnValuesDelegate(KeyValuePair>> returnValue); + + public event ReturnValuesDelegate ReturnValues; + + private int _getCycle; + + /// + /// 毫秒 + /// + public int GetCycle + { + get { return _getCycle; } + set + { + if (value == Timeout.Infinite) + { + if (_timer != null) + { + _timer.Stop(); + } + } + else + { + if (value > 0) + { + _getCycle = value; + } + if (_timer != null) _timer.Interval = _getCycle*1000; + else + { + _timer = new Timer(_getCycle*1000); + _timer.Elapsed += MaintainTasks; + } + _timer.Start(); + } + } + } + + public int MaxRunningTasks + { + get { return _scheduler.MaximumConcurrencyLevel; } + set + { + TaskStop(); + _scheduler = new LimitedConcurrencyLevelTaskScheduler(value); + } + } + + public TaskManager(int maxRunningTask, int getCycle, bool keepConnect) + { + _scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask); + _machines = new HashSet(new BaseMachineEqualityComparer()); + _getCycle = getCycle; + KeepConnect = keepConnect; + } + + public void AddMachine(BaseMachine machine) + { + _machines.Add(machine); + machine.KeepConnect = KeepConnect; + } + + private void MaintainTasks(object sender, System.Timers.ElapsedEventArgs e) + { + foreach (var machine in _machines) + { + RunTask(machine); + } + } + + public void TaskStart() + { + TaskStop(); + _cts = new CancellationTokenSource(); + _tasks = new TaskFactory>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler); + GetCycle = TimeRestore.Restore; + } + + public void TaskStop() + { + GetCycle = Timeout.Infinite; + if (_cts != null) + { + _cts.Cancel(); + } + if (_machines != null) + { + foreach (var machine in _machines) + { + machine.BaseUtility.DisConnect(); + } + } + } + + private void RunTask(BaseMachine machine) + { + try + { + //var ans = machine.GetDatas(); + var ans = _tasks.StartNew(machine.GetDatas).Result; + if (ReturnValues != null) + { + ReturnValues(new KeyValuePair>>(machine.BaseUtility.ConnectionToken, ans)); + } + } + catch (Exception e) + { + + if (ReturnValues != null) + { + ReturnValues(new KeyValuePair>>(machine.BaseUtility.ConnectionToken, null)); + } + } + } + } +} \ No newline at end of file diff --git a/Modbus.Net/ModBus.Net/TcpConnector.cs b/Modbus.Net/ModBus.Net/TcpConnector.cs index 794f44b..bf01ea9 100644 --- a/Modbus.Net/ModBus.Net/TcpConnector.cs +++ b/Modbus.Net/ModBus.Net/TcpConnector.cs @@ -26,6 +26,7 @@ namespace ModBus.Net /// public class TcpConnector : BaseConnector, IDisposable { + public override string ConnectionToken { get { return _host; } } private readonly string _host; @@ -39,7 +40,20 @@ namespace ModBus.Net private readonly int _port; private TcpClient _socketClient; - public int TimeoutTime { get; set; } + private int _timeoutTime; + + public int TimeoutTime + { + get { return _timeoutTime; } + set + { + _timeoutTime = value; + if (_socketClient != null) + { + _socketClient.ReceiveTimeout = _timeoutTime; + } + } + } public TcpConnector(string ipaddress, int port, int timeoutTime) { @@ -77,9 +91,7 @@ namespace ModBus.Net { _socketClient = new TcpClient { - SendTimeout = TimeoutTime, - ReceiveTimeout = TimeoutTime - + ReceiveTimeout = TimeoutTime }; try diff --git a/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs b/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs index 29898bf..c28c6b8 100644 --- a/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs @@ -18,7 +18,7 @@ namespace ModBus.Net protected TcpProtocalLinker(string ip, int port) { - _baseConnector = new TcpConnector(ip, port, 30); + _baseConnector = new TcpConnector(ip, port, 30000); } } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net-vs2013.sln b/Modbus.Net/Modbus.Net-vs2013.sln index d5665f9..0472be4 100644 --- a/Modbus.Net/Modbus.Net-vs2013.sln +++ b/Modbus.Net/Modbus.Net-vs2013.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NA200H.UI.ConsoleApp", "NA200H.UI.Console\NA200H.UI.ConsoleApp.csproj", "{D06F6A34-93F6-4139-B485-8F5686E4E2C9}" EndProject @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NA200H.UI.WPF", "NA200H.UI. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrossLampControl.WebApi", "CrossLampControl.WebApi\CrossLampControl.WebApi.csproj", "{252FDEE7-8671-46D3-A05B-CB7668804700}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simense_S7_200.UI.WPF.TaskTest", "Simense_S7_200.UI.WPF.TaskTest\Simense_S7_200.UI.WPF.TaskTest.csproj", "{02CE1787-291A-47CB-A7F7-929DA1D920A2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {252FDEE7-8671-46D3-A05B-CB7668804700}.Debug|Any CPU.Build.0 = Debug|Any CPU {252FDEE7-8671-46D3-A05B-CB7668804700}.Release|Any CPU.ActiveCfg = Release|Any CPU {252FDEE7-8671-46D3-A05B-CB7668804700}.Release|Any CPU.Build.0 = Release|Any CPU + {02CE1787-291A-47CB-A7F7-929DA1D920A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02CE1787-291A-47CB-A7F7-929DA1D920A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02CE1787-291A-47CB-A7F7-929DA1D920A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02CE1787-291A-47CB-A7F7-929DA1D920A2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Modbus.Net/NA200H.UI.Console/Program.cs b/Modbus.Net/NA200H.UI.Console/Program.cs index 31a7f14..ab75d7e 100644 --- a/Modbus.Net/NA200H.UI.Console/Program.cs +++ b/Modbus.Net/NA200H.UI.Console/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -144,7 +145,8 @@ namespace NA200H.UI.ConsoleApp wrapper.SendReceive(wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct); Console.WriteLine(writeRequestSimenseOutputStruct.AccessResult.ToString()); Console.Read(); - Console.Read(); */ + Console.Read(); + */ } } } diff --git a/Modbus.Net/NA200H.UI.WPF/MainWindow.xaml.cs b/Modbus.Net/NA200H.UI.WPF/MainWindow.xaml.cs index c85dbdc..9088b5f 100644 --- a/Modbus.Net/NA200H.UI.WPF/MainWindow.xaml.cs +++ b/Modbus.Net/NA200H.UI.WPF/MainWindow.xaml.cs @@ -23,7 +23,7 @@ namespace NA200H.UI.WPF //utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.247"); //utility.AddressTranslator = new AddressTranslatorNA200H(); //object[] getNum = utility.GetDatas(0x02, 0x00, "NW1", new KeyValuePair(typeof(ushort), 4)); - utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.241,200"); + utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.191,200"); utility.AddressTranslator = new AddressTranslatorSimense(); object[] getNum = utility.GetDatas(0x02, 0x00, "V1", new KeyValuePair(typeof(ushort), 4)); ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray(getNum);