我正在使用 .NET C# 开发 TCP 服务器。它使用异步 I/O(I/O 完成)来同时处理大量客户端。现在,我将所有 TCP 连接都列在一个列表中,我不断地通过它来寻找任何特定连接的状态机的变化。一旦 I/O 完成设置了某些标志,给定连接的状态机就会更新。
我确信有更好的方法来做到这一点——当前的实现是非常处理器密集型的,因为我没有阻塞等待更新,而是在没有节流的情况下进行轮询。我真的不在乎我的服务器是否在浪费周期,但我猜这是糟糕的设计。我试图找到一种方法来处理特定的连接,只有当 I/O 完成信号有东西要处理时才处理,而在没有时等待(即 sleep )。任何人都可以建议一个好的方法吗?
我在想一些线程同步的事情可能会在循环的主线程等待任何 I/O 完成释放它的情况下工作。但是,有时会使用调用线程执行 I/O 完成(当数据立即可用时等),因此这会导致此解决方案出现问题。
如有任何建议,我们将不胜感激!
这是由主线程执行的(简化的)循环(rgClient 是客户端列表):
//Do communications on each client we currently have connected.
//This loops runs backwards so we can delete elements on the fly
//without have to iterate through more than once.
lock (rgClient)
{
for (i = rgClient.Count - 1; i >= 0; i--)
{
if (!rgClient[i].DoComm())
{
rgClient[i].DoClose();
rgClient.RemoveAt(i);
}
}
}
DoComm() 对连接的状态机执行更新,这涉及执行当前状态的事件,然后在必要时转换到新状态。这是发送简单“ack”数据包的状态类:
class StateAck : State
{
public StateAck(TextBox txtOutputExt, Form fmOwner)
: base(txtOutputExt, fmOwner)
{
fWriting = false;
}
public override bool DoExecute(out Type tpNextState)
{
PktAck pkt;
if (!base.DoExecute(out tpNextState))
{
return false;
}
//Start a write if we haven't yet
if (!fWriting)
{
pkt = new PktAck();
fWriting = true;
return FPutPkt(pkt.rgbSerialize());
}
//Is the read finished / has an error occurred?
if (fDataErrorWrite)
{
return false;
}
//Process the data
if (fDataWritten)
{
tpNextState = typeof(StateIdle);
}
return true;
}
private bool fWriting;
}
每次从主线程调用 DoComm() 时,都会通过 DoExecute() 执行。 99% 的时间,实际上什么都没有发生。当写入(通过调用 FPutPkt() 启动)完成时,一个标志将发出信号,然后下一个状态设置为“空闲”。我想做的是让主线程只检查已完成网络事件并需要更新某些内容的客户端,以避免通过 DoExecute() 进行持续和冗余的传递。
最佳答案
我找到了一个似乎非常有效的解决方案。使用 EventWaitHandler (System.Threading),在每次通过循环的底部自动重置为 WaitOne()。然后任何回调或辅助线程都可以通过调用 EWH.Set() 向 EventWaitHandler 发出信号,这将允许循环进行另一次传递。在不对程序流程进行重大修改的情况下消除轮询循环的 CPU 使用率的好方法。希望对某人有所帮助。
关于C# .NET 服务器轮询多个连接 - 有更好的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4235077/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco