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
{
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 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;
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)
{
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)
{
BaseUtility.DisConnect();
BaseUtility.Disconnect();
}
return ans;
}
public bool Connect()
{
return BaseUtility.Connect();
}
public bool Disconnect()
{
return BaseUtility.Disconnect();
}
}
public struct CommunicationUnit
{
public string StartAddress { get; set; }
public string Area { get; set; }
public int Address { get; set; }
public int GetCount { 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();
}
public bool DisConnect()
public bool Disconnect()
{
return Wrapper.Disconnect();
}

View File

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

View File

@@ -170,7 +170,7 @@ namespace ModBus.Net
{
public bool Equals(BaseMachine x, BaseMachine y)
{
return x.BaseUtility.ConnectionToken == y.BaseUtility.ConnectionToken;
return x.ConnectionToken == y.ConnectionToken;
}
public int GetHashCode(BaseMachine obj)
@@ -182,20 +182,31 @@ namespace ModBus.Net
public class TaskManager
{
private HashSet<BaseMachine> _machines;
private TaskFactory<IEnumerable<IEnumerable<object>>> _tasks;
private TaskFactory<Dictionary<string,string>> _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 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;
@@ -226,9 +237,10 @@ namespace ModBus.Net
else
{
_timer = new Timer(_getCycle*1000);
_timer.Elapsed += MaintainTasks;
_timer.Elapsed += MaintainTasks;
}
_timer.Start();
MaintainTasks(null,null);
}
}
}
@@ -253,15 +265,21 @@ namespace ModBus.Net
public void AddMachine(BaseMachine machine)
{
_machines.Add(machine);
machine.KeepConnect = KeepConnect;
lock (_machines)
{
_machines.Add(machine);
}
}
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();
_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;
}
@@ -282,9 +300,12 @@ namespace ModBus.Net
}
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;
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)
@@ -305,7 +326,7 @@ namespace ModBus.Net
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);
}
/// <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>
/// 将byte数组中相应的位置转换为byte数字
/// </summary>