2015-04-14 update 1 Add Task Manager
This commit is contained in:
@@ -8,6 +8,10 @@ namespace ModBus.Net
|
||||
{
|
||||
public abstract class BaseConnector
|
||||
{
|
||||
public abstract string ConnectionToken { get; }
|
||||
/// <summary>
|
||||
/// 是否处于连接状态
|
||||
/// </summary>
|
||||
public abstract bool IsConnected { get; }
|
||||
/// <summary>
|
||||
/// 连接PLC
|
||||
|
||||
54
Modbus.Net/ModBus.Net/BaseMachine.cs
Normal file
54
Modbus.Net/ModBus.Net/BaseMachine.cs
Normal file
@@ -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<CommunicationUnit> GetAddresses { get; set; }
|
||||
|
||||
public bool KeepConnect { get; set; }
|
||||
|
||||
public BaseUtility BaseUtility { get; protected set; }
|
||||
|
||||
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses) : this(getAddresses, false)
|
||||
{
|
||||
}
|
||||
|
||||
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses, bool keepConnect)
|
||||
{
|
||||
GetAddresses = getAddresses;
|
||||
KeepConnect = keepConnect;
|
||||
}
|
||||
|
||||
public IEnumerable<IEnumerable<object>> GetDatas()
|
||||
{
|
||||
List<object[]> ans = new List<object[]>();
|
||||
if (!BaseUtility.IsConnected)
|
||||
{
|
||||
BaseUtility.Connect();
|
||||
}
|
||||
foreach (var getAddress in GetAddresses)
|
||||
{
|
||||
ans.Add(BaseUtility.GetDatas(2, 0, getAddress.StartAddress, new KeyValuePair<Type, int>(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; }
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,13 @@ namespace ModBus.Net
|
||||
/// 协议连接断开
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool Disconnect();
|
||||
|
||||
public virtual bool Disconnect()
|
||||
{
|
||||
if (ProtocalLinker != null)
|
||||
{
|
||||
return ProtocalLinker.Disconnect();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,21 @@ namespace ModBus.Net
|
||||
/// 协议收发主体
|
||||
/// </summary>
|
||||
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<T>(byte belongAddress, byte masterAddress, string startAddress,
|
||||
int getByteCount)
|
||||
{
|
||||
var getBytes = GetDatas(belongAddress, masterAddress, startAddress, new KeyValuePair<Type, int>(typeof(T), getByteCount));
|
||||
return ValueHelper.Instance.ObjectArrayToDestinationArray<T>(getBytes);
|
||||
}
|
||||
|
||||
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
|
||||
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
|
||||
{
|
||||
@@ -82,5 +103,15 @@ namespace ModBus.Net
|
||||
/// <param name="setTime">设置PLC时间</param>
|
||||
/// <returns>设置是否成功</returns>
|
||||
public abstract bool SetTime(byte belongAddress, DateTime setTime);
|
||||
|
||||
public bool Connect()
|
||||
{
|
||||
return Wrapper.Connect();
|
||||
}
|
||||
|
||||
public bool DisConnect()
|
||||
{
|
||||
return Wrapper.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace ModBus.Net
|
||||
protected ComProtocalLinker(string com)
|
||||
{
|
||||
//初始化连对象
|
||||
_baseConnector = new ComConnector(com);
|
||||
_baseConnector = new ComConnector(com, 30000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<Compile Include="AsyncHelper.cs" />
|
||||
<Compile Include="BaseProtocal.cs" />
|
||||
<Compile Include="BaseUtility.cs" />
|
||||
<Compile Include="BaseMachine.cs" />
|
||||
<Compile Include="ComConnector.cs" />
|
||||
<Compile Include="ModbusMachine.cs" />
|
||||
<Compile Include="ModbusProtocalLinkerBytesExtend.cs" />
|
||||
<Compile Include="ModbusUtility.cs" />
|
||||
<Compile Include="ComProtocalLinker.cs" />
|
||||
@@ -72,6 +74,7 @@
|
||||
<Compile Include="ModbusProtocal.cs" />
|
||||
<Compile Include="ModbusTcpProtocal.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SimenseMachine.cs" />
|
||||
<Compile Include="SimenseProtocal.cs" />
|
||||
<Compile Include="SimenseStructDefinition.cs" />
|
||||
<Compile Include="SimenseTcpProtocal.cs" />
|
||||
|
||||
@@ -45,11 +45,6 @@ namespace ModBus.Net
|
||||
{
|
||||
return ProtocalLinker.Connect();
|
||||
}
|
||||
|
||||
public override bool Disconnect()
|
||||
{
|
||||
return ProtocalLinker.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#region 读PLC数据
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
/// <param name="content">接收协议的内容</param>
|
||||
/// <returns>协议是否是正确的</returns>
|
||||
public abstract bool CheckRight(byte[] content);
|
||||
public virtual bool CheckRight(byte[] content)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议内容扩展,发送时根据需要扩展
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -77,10 +77,5 @@ namespace ModBus.Net
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Disconnect()
|
||||
{
|
||||
return ProtocalLinker.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace ModBus.Net
|
||||
{
|
||||
public override bool CheckRight(byte[] content)
|
||||
{
|
||||
if (!base.CheckRight(content)) return false;
|
||||
switch (content[5])
|
||||
{
|
||||
case 0xd0:
|
||||
|
||||
@@ -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)
|
||||
|
||||
313
Modbus.Net/ModBus.Net/TaskManager.cs
Normal file
313
Modbus.Net/ModBus.Net/TaskManager.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the current thread is processing work items.
|
||||
/// </summary>
|
||||
[ThreadStatic]
|
||||
private static bool _currentThreadIsProcessingItems;
|
||||
/// <summary>
|
||||
/// The list of tasks to be executed.
|
||||
/// </summary>
|
||||
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
|
||||
/// <summary>
|
||||
/// The maximum concurrency level allowed by this scheduler.
|
||||
/// </summary>
|
||||
private readonly int _maxDegreeOfParallelism;
|
||||
/// <summary>
|
||||
/// Whether the scheduler is currently processing work items.
|
||||
/// </summary>
|
||||
private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
|
||||
/// specified degree of parallelism.
|
||||
/// </summary>
|
||||
/// <param name="maxDegreeOfParallelism">
|
||||
/// The maximum degree of parallelism provided by this scheduler.
|
||||
/// </param>
|
||||
public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
|
||||
{
|
||||
if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
|
||||
_maxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a task to the scheduler.
|
||||
/// </summary>
|
||||
/// <param name="task">
|
||||
/// The task to be queued.
|
||||
/// </param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Informs the ThreadPool that there's work to be executed for this scheduler.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>Attempts to execute the specified task on the current thread.</summary>
|
||||
/// <param name="task">The task to be executed.</param>
|
||||
/// <param name="taskWasPreviouslyQueued"></param>
|
||||
/// <returns>Whether the task could be executed on the current thread.</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to remove a previously scheduled task from the scheduler.
|
||||
/// </summary>
|
||||
/// <param name="task">
|
||||
/// The task to be removed.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Whether the task could be found and removed.
|
||||
/// </returns>
|
||||
protected sealed override bool TryDequeue(Task task)
|
||||
{
|
||||
lock (_tasks) return _tasks.Remove(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum concurrency level supported by this scheduler.
|
||||
/// </summary>
|
||||
public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerable of the tasks currently scheduled on this scheduler.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An enumerable of the tasks currently scheduled.
|
||||
/// </returns>
|
||||
protected sealed override IEnumerable<Task> 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<BaseMachine>
|
||||
{
|
||||
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<BaseMachine> _machines;
|
||||
private TaskFactory<IEnumerable<IEnumerable<object>>> _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<string, IEnumerable<IEnumerable<object>>> returnValue);
|
||||
|
||||
public event ReturnValuesDelegate ReturnValues;
|
||||
|
||||
private int _getCycle;
|
||||
|
||||
/// <summary>
|
||||
/// 毫秒
|
||||
/// </summary>
|
||||
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<BaseMachine>(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<IEnumerable<IEnumerable<object>>>(_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<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, ans));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
if (ReturnValues != null)
|
||||
{
|
||||
ReturnValues(new KeyValuePair<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ namespace ModBus.Net
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Type, int>(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<Type, int>(typeof(ushort), 4));
|
||||
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
|
||||
|
||||
Reference in New Issue
Block a user