Tej*_*ora 11 c# simulation multithreading task-parallel-library
我正在编写一个客户端模拟程序,其中所有模拟客户端都针对服务器运行一些预定义的例程 - 这是一个在具有四个实例的azure中运行的Web服务器.
连接到服务器后,所有模拟客户端都运行相同的例程.
在任何时候,我都希望使用我的程序模拟300到800个客户端.
我的问题是:我应该创建N个客户端类实例并在N个不同的线程中运行它们吗?要么
我应该使用任务库来做这些事吗?
Eri*_*ert 21
你当然不应该创建800个线程.
我们在这里退一步吧.您有一个名为"服务器"的设备,它从"客户端"接收"请求"并将"响应"发送回这些客户端.我们假设这些请求是邮局提供的纸张,而回复是包含书籍的方框,也由邮局提供.
您希望模拟 800个客户端以测试服务器.
让我们假设一个线程是一个人而一个处理器就是一个主席.一个人只能坐在椅子上做工作.
创建800个线程相当于外出和雇佣800人,并支付每个人向服务器发送一封信.但是你只有四把椅子,所以800人必须轮流使用椅子.
这在现实生活中将是一个荒谬的解决方案.像人一样,线程非常昂贵.您应该最小化您创建的线程数.
那么,您是否应该通过任务工厂创建800个任务并让TPL为您进行并行化?
不,你也不应该这样做.TPL有一群人(线程)可以从中抽取,它会尝试安排事情,以便工资单上没有人可以坐在椅子上.但是你的任务不是"主持" - - 人们将坐在椅子上,将请求发送到服务器,然后在等待响应回来时离开椅子.在他们等待的同时,TPL现在必须雇用更多人来为其他任务提供服务.
命中Web服务器是I/O绑定的; 您应该只为CPU绑定的任务创建线程池任务.
正确的解决方案是雇用两个人.
一个人 - "I/O完成线程" - 除了丢弃邮箱中的请求并检查传入的包之外什么都不做.另一个人 - "模拟"人 - 计算出模拟800个客户的正确"时间表".模拟人员制定计划,然后进入睡眠状态.当需要向服务器发送另一个请求时,她会醒来.当她醒来时,她告诉I/O完成线程将此信件丢弃在邮箱中,并在响应进入时将其唤醒.然后她回到睡眠状态,直到发送另一个请求或响应为止需要验证的是.
您应该做的是(1)获取C#5的beta版本并用于async/await创建向服务器发送请求的任务,然后将控制权交还给消息循环,直到它发送另一个请求或响应到来为止或者,如果您不想使用C#5,则应创建任务完成源,并设置具有正确延续的任务.
简而言之:处理许多并行I/O任务的正确方法是创建非常少量的线程,每个线程一次只执行非常少量的工作.让I/O完成线程处理I/O的细节.您不需要雇用800人来模拟发送800个字母. 雇用两个人,一个人看邮箱,另一个人写信.