我设计了一个应用程序(C#with .net 4.5),它使用请求响应机制连接到多个支持以太网的硬件设备(最多100个设备)以进行数据传输。
每个硬件设备都配置了唯一的IP地址和端口,我的应用程序使用tcpclient类连接并与此设备通信。
现在我的要求是,
即。如果我连接到设备数据传输应该发生,并且只有在它之后它应该设置下一次执行的间隔。(最可能在回调函数本身)
为了实现这一点,我想使用threading.timer,为此我可以在回调函数本身设置线程间隔。我正在测试这个并且似乎最初工作,我相信我可以进一步优化此代码以在生产环境中工作。
但是进一步的Google我开始相信任务并行库更有效率,因为我正在研究.net 4.5我应该使用这个而不是经典的threading.timer类。
但由于TPL与threading没有完全相同。我必须努力使其完全符合我的要求。
所以我的问题是,如果我使用TPL进行一些自定义而不是threading.timer,我真的会获得任何性能提升,或者我应该继续使用threading.timer。
答案 0 :(得分:0)
我建议在线程和TPL上使用Microsoft的Reactive Framework(NuGet“System.Reactive”)。这就是我要做的事情:
首先定义一个TimeSpan
值数组,可用于更改每个设备的计划:
int devices = 3;
TimeSpan[] timerTimeSpans =
Enumerable
.Range(0, devices)
.Select(x => TimeSpan.FromMilliseconds(2000))
.ToArray();
我的默认值为2000毫秒。
然后定义一个从设备读取的方法:
public Task<DeviceResult> DeviceFetchAsync(int device_number, Action<TimeSpan> reschedule)
{
if (device_number == 1)
{
reschedule(TimeSpan.FromMilliseconds(10000));
}
return Task.Factory.StartNew(() => new DeviceResult()
{
DeviceNumber = device_number
});
}
public class DeviceResult
{
public int DeviceNumber;
}
它包含Action<TimeSpan> reschedule
以更改此特定设备的计划。
现在,对于设置所有定时器和从设备读取的Rx查询:
IObservable<DeviceResult> query =
Observable
.Range(0, devices)
.Select(n =>
Observable
.Generate(0, x => true, x => x + 1, x => x, x => timerTimeSpans[n])
.SelectMany(x =>
Observable
.FromAsync(() => DeviceFetchAsync(n, ts => timerTimeSpans[n] = ts))))
.Merge();
最后订阅整个事情:
IDisposable subscription =
query
.Subscribe(r => Console.WriteLine(r.DeviceNumber));
如果你想停止一切,只需subscription.Dispose();
。
就是这样。这就是所有的代码。我已经测试了这个并且工作正常。