2015-04-15 update 1 Update about TaskManager

This commit is contained in:
parallelbgls@outlook.com
2015-04-15 10:17:31 +08:00
parent 249c6fe36c
commit 5485bb1162
6 changed files with 242 additions and 30 deletions

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public abstract class AddressFormater
{
public abstract string FormatAddress(string area, int address);
}
public class AddressFormaterSimense : AddressFormater
{
public override string FormatAddress(string area, int address)
{
if (area.ToUpper() == "DB")
{
return area.ToUpper() + "." + "DB" + address;
}
else
{
return area.ToUpper() + address;
}
}
}
public class AddressFormaterBase : AddressFormater
{
public override string FormatAddress(string area, int address)
{
return area + "." + address;
}
}
public class AddressFormaterNA200H : AddressFormater
{
public override string FormatAddress(string area, int address)
{
return area + address;
}
}
}

View File

@@ -8,47 +8,129 @@ using System.Threading.Tasks;
namespace ModBus.Net namespace ModBus.Net
{ {
public abstract class BaseMachine public abstract class BaseMachine : IMachineProperty
{ {
public IEnumerable<CommunicationUnit> GetAddresses { get; set; } public string ProjectName { get; set; }
public string MachineName { get; set; }
public string ConnectionToken { get { return BaseUtility.ConnectionToken; } }
protected AddressFormater AddressFormater { get; set; }
protected AddressCombiner AddressCombiner { get; set; }
protected IEnumerable<CommunicationUnit> CommunicateAddresses
{
get { return AddressCombiner.Combine(GetAddresses); }
}
public IEnumerable<AddressUnit> GetAddresses { get; set; }
public bool KeepConnect { get; set; } public bool KeepConnect { get; set; }
public BaseUtility BaseUtility { get; protected set; } protected BaseUtility BaseUtility { get; set; }
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses) : this(getAddresses, false) protected BaseMachine(IEnumerable<AddressUnit> getAddresses)
: this(getAddresses, false)
{ {
} }
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses, bool keepConnect) protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect)
{ {
GetAddresses = getAddresses; GetAddresses = getAddresses;
KeepConnect = keepConnect; KeepConnect = keepConnect;
} }
public IEnumerable<IEnumerable<object>> GetDatas() public Dictionary<string,string> GetDatas()
{ {
List<object[]> ans = new List<object[]>(); Dictionary<string, string> ans = new Dictionary<string, string>();
if (!BaseUtility.IsConnected) if (!BaseUtility.IsConnected)
{ {
BaseUtility.Connect(); BaseUtility.Connect();
} }
foreach (var getAddress in GetAddresses) foreach (var communicateAddress in CommunicateAddresses)
{ {
ans.Add(BaseUtility.GetDatas(2, 0, getAddress.StartAddress, new KeyValuePair<Type, int>(getAddress.DataType, getAddress.GetCount))); var datas = BaseUtility.GetDatas<byte>(2, 0, AddressFormater.FormatAddress(communicateAddress.Area,communicateAddress.Address), communicateAddress.GetCount);
int pos = 0;
while (pos < communicateAddress.GetCount)
{
var address =
GetAddresses.SingleOrDefault(
p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address);
if (address != null)
{
ans.Add(address.CommunicationTag, (String.Format("{0:#0.000}", Double.Parse(ValueHelper.Instance.GetValue(datas, ref pos, address.DataType).ToString()) * address.Zoom)));
}
else
{
pos++;
}
}
} }
if (!KeepConnect) if (!KeepConnect)
{ {
BaseUtility.DisConnect(); BaseUtility.Disconnect();
} }
return ans; return ans;
} }
public bool Connect()
{
return BaseUtility.Connect();
}
public bool Disconnect()
{
return BaseUtility.Disconnect();
}
} }
public struct CommunicationUnit public struct CommunicationUnit
{ {
public string StartAddress { get; set; } public string Area { get; set; }
public int Address { get; set; }
public int GetCount { get; set; } public int GetCount { get; set; }
public Type DataType { get; set; } public Type DataType { get; set; }
} }
public class AddressUnit
{
public int Id { get; set; }
/// <summary>
/// 数据所属的区域Modbus指通讯码PROFINET指数据块
/// </summary>
public string Area { get; set; }
public int Address { get; set; }
public Type DataType { get; set; }
/// <summary>
/// 放缩比例
/// </summary>
public double Zoom { get; set; }
/// <summary>
/// 通讯标识名称
/// </summary>
public string CommunicationTag { get; set; }
public string Name { get; set; }
}
public struct AddressUnitEqualityComparer : IEqualityComparer<AddressUnit>
{
public bool Equals(AddressUnit x, AddressUnit y)
{
return x.Area.ToUpper() == y.Area.ToUpper() && x.Address == y.Address;
}
public int GetHashCode(AddressUnit obj)
{
return obj.GetHashCode();
}
}
public interface IMachineProperty
{
string ProjectName { get; set; }
string MachineName { get; set; }
string ConnectionToken { get; }
}
} }

View File

@@ -109,7 +109,7 @@ namespace ModBus.Net
return Wrapper.Connect(); return Wrapper.Connect();
} }
public bool DisConnect() public bool Disconnect()
{ {
return Wrapper.Disconnect(); return Wrapper.Disconnect();
} }

View File

@@ -47,6 +47,8 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AddressCombiner.cs" />
<Compile Include="AddressFormater.cs" />
<Compile Include="AddressTranslator.cs" /> <Compile Include="AddressTranslator.cs" />
<Compile Include="AsyncHelper.cs" /> <Compile Include="AsyncHelper.cs" />
<Compile Include="BaseProtocal.cs" /> <Compile Include="BaseProtocal.cs" />

View File

@@ -170,7 +170,7 @@ namespace ModBus.Net
{ {
public bool Equals(BaseMachine x, BaseMachine y) public bool Equals(BaseMachine x, BaseMachine y)
{ {
return x.BaseUtility.ConnectionToken == y.BaseUtility.ConnectionToken; return x.ConnectionToken == y.ConnectionToken;
} }
public int GetHashCode(BaseMachine obj) public int GetHashCode(BaseMachine obj)
@@ -182,20 +182,31 @@ namespace ModBus.Net
public class TaskManager public class TaskManager
{ {
private HashSet<BaseMachine> _machines; private HashSet<BaseMachine> _machines;
private TaskFactory<IEnumerable<IEnumerable<object>>> _tasks; private TaskFactory<Dictionary<string,string>> _tasks;
private TaskScheduler _scheduler; private TaskScheduler _scheduler;
private CancellationTokenSource _cts; private CancellationTokenSource _cts;
private Timer _timer; private Timer _timer;
private bool _keepConnect; 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 bool KeepConnect
{
get { return _keepConnect; }
set
{
TaskStop();
_keepConnect = value;
lock (_machines)
{
foreach (var machine in _machines)
{
machine.KeepConnect = _keepConnect;
}
}
}
}
public delegate void ReturnValuesDelegate(KeyValuePair<string, Dictionary<string,string>> returnValue);
public event ReturnValuesDelegate ReturnValues; public event ReturnValuesDelegate ReturnValues;
@@ -229,6 +240,7 @@ namespace ModBus.Net
_timer.Elapsed += MaintainTasks; _timer.Elapsed += MaintainTasks;
} }
_timer.Start(); _timer.Start();
MaintainTasks(null,null);
} }
} }
} }
@@ -253,15 +265,21 @@ namespace ModBus.Net
public void AddMachine(BaseMachine machine) public void AddMachine(BaseMachine machine)
{ {
_machines.Add(machine);
machine.KeepConnect = KeepConnect; machine.KeepConnect = KeepConnect;
lock (_machines)
{
_machines.Add(machine);
}
} }
private void MaintainTasks(object sender, System.Timers.ElapsedEventArgs e) private void MaintainTasks(object sender, System.Timers.ElapsedEventArgs e)
{ {
foreach (var machine in _machines) lock (_machines)
{ {
RunTask(machine); foreach (var machine in _machines)
{
RunTask(machine);
}
} }
} }
@@ -269,7 +287,7 @@ namespace ModBus.Net
{ {
TaskStop(); TaskStop();
_cts = new CancellationTokenSource(); _cts = new CancellationTokenSource();
_tasks = new TaskFactory<IEnumerable<IEnumerable<object>>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler); _tasks = new TaskFactory<Dictionary<string,string>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
GetCycle = TimeRestore.Restore; GetCycle = TimeRestore.Restore;
} }
@@ -282,9 +300,12 @@ namespace ModBus.Net
} }
if (_machines != null) if (_machines != null)
{ {
foreach (var machine in _machines) lock (_machines)
{ {
machine.BaseUtility.DisConnect(); foreach (var machine in _machines)
{
machine.Disconnect();
}
} }
} }
} }
@@ -297,7 +318,7 @@ namespace ModBus.Net
var ans = _tasks.StartNew(machine.GetDatas).Result; var ans = _tasks.StartNew(machine.GetDatas).Result;
if (ReturnValues != null) if (ReturnValues != null)
{ {
ReturnValues(new KeyValuePair<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, ans)); ReturnValues(new KeyValuePair<string, Dictionary<string,string>>(machine.ConnectionToken, ans));
} }
} }
catch (Exception e) catch (Exception e)
@@ -305,7 +326,7 @@ namespace ModBus.Net
if (ReturnValues != null) if (ReturnValues != null)
{ {
ReturnValues(new KeyValuePair<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, null)); ReturnValues(new KeyValuePair<string, Dictionary<string,string>>(machine.ConnectionToken, null));
} }
} }
} }

View File

@@ -155,6 +155,69 @@ namespace ModBus.Net
return BitConverter.GetBytes(value); return BitConverter.GetBytes(value);
} }
/// <summary>
/// 将byte数组中相应的位置转换为对应类型的数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <param name="t"></param>
/// <returns></returns>
public virtual object GetValue(byte[] data, ref int pos, Type t)
{
switch (t.FullName)
{
case "System.Int16":
{
short value = Instance.GetShort(data, ref pos);
return value;
}
case "System.Int32":
{
int value = Instance.GetInt(data, ref pos);
return value;
}
case "System.Int64":
{
long value = Instance.GetLong(data, ref pos);
return value;
}
case "System.UInt16":
{
ushort value = Instance.GetUShort(data, ref pos);
return value;
}
case "System.UInt32":
{
uint value = Instance.GetUInt(data, ref pos);
return value;
}
case "System.UInt64":
{
ulong value = Instance.GetULong(data, ref pos);
return value;
}
case "System.Single":
{
float value = Instance.GetFloat(data, ref pos);
return value;
}
case "System.Double":
{
double value = Instance.GetDouble(data, ref pos);
return value;
}
case "System.Byte":
{
byte value = Instance.GetByte(data, ref pos);
return value;
}
default:
{
throw new NotImplementedException("没有实现除整数以外的其它转换方式");
}
}
}
/// <summary> /// <summary>
/// 将byte数组中相应的位置转换为byte数字 /// 将byte数组中相应的位置转换为byte数字
/// </summary> /// </summary>