Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net 4.5时代,哪个线程.timer或任务并行库更有效_C#_Multithreading_Timer_Task Parallel Library - Fatal编程技术网

C# 在.net 4.5时代,哪个线程.timer或任务并行库更有效

C# 在.net 4.5时代,哪个线程.timer或任务并行库更有效,c#,multithreading,timer,task-parallel-library,C#,Multithreading,Timer,Task Parallel Library,我设计了一个带有.net 4.5的应用程序C,它连接到多个支持以太网的硬件设备,最多100个设备,用于使用请求-响应机制进行数据传输 每个硬件设备都配置了唯一的ip地址和端口,我的应用程序使用tcpclient类与这些设备进行连接和通信 现在我的要求是, 使应用程序多线程,以便它能够同时连接所有设备。每个连接的线程数 与所有这些设备发生的通信是重复的,即在每个特定间隔后,它应连接到所有设备,以便全天候进行数据传输。 我还有一个额外的要求是,一旦函数回调函数完成执行,就应该配置间隔。因为某些时间设

我设计了一个带有.net 4.5的应用程序C,它连接到多个支持以太网的硬件设备,最多100个设备,用于使用请求-响应机制进行数据传输

每个硬件设备都配置了唯一的ip地址和端口,我的应用程序使用tcpclient类与这些设备进行连接和通信

现在我的要求是,

使应用程序多线程,以便它能够同时连接所有设备。每个连接的线程数 与所有这些设备发生的通信是重复的,即在每个特定间隔后,它应连接到所有设备,以便全天候进行数据传输。 我还有一个额外的要求是,一旦函数回调函数完成执行,就应该配置间隔。因为某些时间设备延迟了响应,所以我无法使用睡眠、延迟或等效功能。在这种情况下,新的迭代可能会开始,即使最后一次迭代没有完成,这是我想要阻止的。 i、 如果我连接到设备,数据传输应该发生,并且只有在这之后,它才应该设置下一次执行的间隔。很可能是在回调函数本身中

为了实现这一点,我考虑使用threading.timer,为此我可以在回调函数本身中设置线程间隔。我正在测试这一点,并且在开始阶段似乎可以工作,我相信我可以进一步优化这段代码,使其在生产环境中工作

但在Google上做得更深入,我开始相信任务并行库更有效,因为我正在使用.NET4.5,所以我应该使用这个类,而不是经典的threading.timer类

但由于TPL并没有与threading.timer完全相同的功能,所以我必须对其进行改进,使其完全符合我的要求


因此,我的问题是,如果我使用TPL进行一些定制,而不是使用threading.timer,那么我真的会获得任何性能提升,还是应该继续使用threading.timer

我建议使用微软的反应式框架NuGet系统。通过线程和TPL来实现这一点。下面是我要做的:

首先定义可用于更改每个设备调度的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;
}
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();
如果要停止所有操作,只需执行subscription.Dispose


就这样。这就是全部代码。我已经对此进行了测试,效果很好。

将应用程序设置为多线程,以便它能够同时连接所有设备,这是一种误解,会让您走上错误的道路。使用异步IO,而不是每个连接一个线程。@spender我知道了。虽然我不确定,但我相信即使我使用每个连接的线程,它也不会影响性能,因为我的连接有限,可能永远不会超过100个线程,那么根本就没有线程呢?IO在操作系统级别是异步的。阻塞是模拟的。通过使用async/await,您可以在不使用任何线程的情况下使用本机异步功能。@BoeseB async/await是TPL的一项功能。@HarshalSam您应该重新考虑您的方法。连接到100个物联网设备的服务器是一个非常大的安全漏洞。如果该设备能够监听,它就可以并且将被黑客攻击。物联网设备太弱,无法安装强大的防火墙和反恶意软件防御。但它位于公司网络内部,并不意味着它是安全的——它意味着任何被破坏的公司PC都可以对它们进行黑客攻击。
IDisposable subscription =
    query
        .Subscribe(r => Console.WriteLine(r.DeviceNumber));