如何在短时间内发送消息

时间:2014-03-06 15:00:27

标签: c# performance

我试图在给定的时间跨度内发送大约20条消息。我想记录收到请求的时间。 现在这个时间如下所示

        var startTime = DateTime.Now;
        var timeoutSpan = TimeSpan.FromMilliseconds(1000);
        var count = 0;
        while ((DateTime.Now - startTime) <= timeoutSpan)
        {
            foreach (string message in messages)
            {
                txtRequest.Text = message;
                //this sends request to my service that logs a request
                sendMessageResult = client.SendMessage("Test", txtRequest.Text);
                 count++;
            }

        }

假设我在时间= 2014-03-06 09:46:47:334 AM发送消息

我希望循环中所有消息的请求的接收时间非常相似,但现在差距如下:

请求A时间= 2014-03-06 09:46:47:334 AM
数:1个
请求B时间= 2014-03-06 09:46:47:385上午 数:2个
要求C时间= 2014-03-06 09:46:47:414 AM

的App.config

  <system.serviceModel>
  <behaviors>
     <serviceBehaviors>
    <behavior name="meta">
      <serviceMetadata httpGetEnabled="true" />
      </behavior>
  </serviceBehaviors>
  </behaviors>
   <services>
  <service behaviorConfiguration="meta" name="MyService.Operator">
    <endpoint address="" binding="basicHttpBinding" contract="MyService.IOperator" />

    <host>
      <baseAddresses>
       <add baseAddress="http://MyService" />  
      </baseAddresses>
    </host>
  </service>
</services>

如何使请求的毫秒数非常接近或相等(如果可能)?你可以看到请求B有.385毫秒我怎样才能发出一个同时发送的请求?

2 个答案:

答案 0 :(得分:1)

你可以这样做:

Parallel.For(0, 20, p =>
{
    var sendMessageResult = client.SendUNIMessage("Test", messages[p]);
});

答案 1 :(得分:0)

如果你在我的有限测试中利用TPL(同一个盒子上的客户端和服务器以及具有GB网络连接的单独盒子上的客户端和服务器)如​​果我不重用wcf-client但是创建了一个更好的结果每个线程都有一个新的。我使用默认的VS2010 WcfApplication模板作为x64 .Net 4.0可执行文件进行了测试。

我的代码如下所示:

// no multi-threading, one client
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
using (var wc = new ServiceReference1.Service1Client())
{
    for (int x = 0; x < 200; x++)
    {
        wc.SendMessage("test", messages[x]);
    }
}
sw.Stop();
Console.WriteLine("plain for: {0} ms", sw.ElapsedMilliseconds);
sw.Reset();

// classic Threadpool 
sw.Start();
using (var wc = new ServiceReference1.Service1Client())
{
    var _countdown = new CountdownEvent(200);
    for (int x = 0; x < 200; x++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                // try/catch to guarantee that _countdown.Signal is always called
                try
                {
                    wc.SendMessage("Test",messages[(int) state]);
                }
                finally
                {
                    _countdown.Signal();
                }
            }, x);
    }
    _countdown.Wait();
}
sw.Stop();
Console.WriteLine("ThreadPool: {0} ms", sw.ElapsedMilliseconds);
sw.Reset();

// multi-threading, one wcf client
sw.Start();
using (var wc = new ServiceReference1.Service1Client())
{
    Parallel.For(0, 200, x =>
        {
            wc.SendMessage("test", messages[x]);
        });
}
sw.Stop();
Console.WriteLine("tpl  paralel for: {0} ms", sw.ElapsedMilliseconds);
sw.Reset();

// multi-threading, client per thread
sw.Start();
int cnt = 0;
Parallel.For(
    0, 
    200, 
    () => { return new ServiceReference1.Service1Client(); },
    (x,pls,wc) =>
    {
        wc.SendMessage("test", messages[x]);
        System.Threading.Interlocked.Increment(ref cnt); // for all done check
        return wc;
    }, 
    client => {client.Close(); ((IDisposable) client).Dispose();}
);                
sw.Stop();
Console.WriteLine("tpl wc per thread paralel for: {0} ms ({1})", sw.ElapsedMilliseconds, cnt);

我的网络环境中的典型时间(发布版本):

plain for: 769 ms
threadpool: 609 ms
tpl  paralel for: 499 ms
tpl wc per thread paralel for: 225 ms

当在同一个盒子上运行所有东西时,plain和tpl paralel之间的时间变得更加紧密。

请注意,由于网络和/或CPU负载,时间和时间会突然跳跃。我没有分析CPU或内存负载。

根据此测试和设置,您可以得出结论Parallel.For每个线程创建的webclient是最快的。

在优化性能时,请确保继续测试,在目标硬件上使用发布版本,并且每次运行只更改一个参数/设计选项。