C#WPF代码在Visual Studio中比从控制台运行得更快,而在另一个文件夹中运行得更慢

时间:2014-10-31 17:39:38

标签: c# wpf performance visual-studio

这是我见过的最奇怪的问题,我希望你觉得它很有趣。我创建了一个C#WPF示例,它将IP数据包作为典型的数据包嗅探器(下面的源代码)进行侦听,并将一些数据打印到屏幕上。我有非常一致和可重复的行为,但有两个结果(快速和慢速)。

先决条件:由于IP套接字代码,以管理员身份运行Visual Studio 2010。

如果我在x86 Release模式下在Visual Studio中运行应用程序(单击绿色箭头),它每秒处理大约300个数据包(快速)。完善。如果我在调试模式下运行它,它每秒处理大约1个数据包(慢)。这是可以理解的,因为调试模式增加了开销。但是,坚持下去,这就是它变得奇怪的地方。

问题/问题

  1. 如果我将解决方案复制到另一个文件夹并从Visual Studio中运行(x86 Release,就像以前一样),它运行缓慢。但是,如果我将相同的解决方案复制回原始文件夹路径,它会快速运行。为什么呢?

  2. 如果我从命令提示符以管理员身份运行x86 Release模式可执行文件,它每秒处理大约1(慢)。为什么? (编辑:这可能是因为VS主机进程的任何性能提升都不存在于VS之外。)

  3. 因此,代码只有在原始文件夹中从Visual Studio(x86 Release)运行时才会快速执行。

    我尝试过的其他内容:

    1. 清理并手动敲击obj和bin文件夹......并重建解决方案。
    2. 清理注册表并删除引用应用程序或路径的所有行。
    3. 删除了Windows防火墙中引用应用程序名称的所有条目。
    4. 已禁用防病毒软件,并将该应用程序添加到排除列表中。
    5. 运行Visual Studio输出文本的差异比较(BeyondCompare)。
    6. 创建了新的解决方案并将代码复制/粘贴到它们中,如果名称不同或位于同一文件夹中,它们仍然运行缓慢。
    7. 与WireShark捕获相比,每秒显示大约300个数据包。
    8. 启用/禁用VS主机进程。如果解决方案仅在原始路径中,则启用运行速度更快。
    9. 重新启动
    10. MainWindow.xaml

         <Window x:Class="WpfSingle.MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  Title="MainWindow" Height="350" Width="525" Closing="Window_Closing">
              <Grid>
                  <ScrollViewer>
                      <TextBlock Name="textBlock1"></TextBlock>
                  </ScrollViewer>
              </Grid>
          </Window>
      

      MainWindow.xaml.cs

      using System;
      using System.Text;
      using System.Windows;
      using System.Net.Sockets;
      using System.Net;
      
      namespace WpfSingle
          {
              public partial class MainWindow : Window
              {
                  private static System.Threading.Thread _processingThread;
                  private bool _killThread;
                  private Socket _socket;
                  private const int PACKET_MAX_SIZE = 32768;
                  private byte[] _bytesIn;
                  private byte[] _bytesOut;
                  private byte[] _byteData;
                  private int _bytesReceived;
                  private int _packetCounter;
                  private string Interface = "192.168.1.42";
                  private StringBuilder _sbTextOut;
      
                  public MainWindow()
                  {
                      InitializeComponent();
                      _sbTextOut = new StringBuilder();
      
                      try
                      {
                          _processingThread = new System.Threading.Thread(ThreadProcess);
                          _processingThread.Start();
                      }
                      catch (Exception ex)
                      {
                          Console.Error.WriteLine(ex.Message);
                      }
                  }
      
                  private void ThreadProcess()
                  {
                      _killThread = false;
                      _byteData = new byte[PACKET_MAX_SIZE];
                      _bytesIn = new byte[4] { 1, 0, 0, 0 };
                      _bytesOut = new byte[4] { 1, 0, 0, 0 };
                      _packetCounter = 0;
      
                      try
                      {
                          _socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
                          _socket.Bind(new IPEndPoint(IPAddress.Parse(Interface), 0));
                          _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
                          _socket.IOControl(IOControlCode.ReceiveAll, _bytesIn, _bytesOut);
                      }
                      catch (Exception ex)
                      {
                          if (_socket != null) _socket.Close();
                          Console.Error.WriteLine(ex.Message);
                      }
      
                      while (true)
                      {
                          OnThreadProcess();
                          if (_killThread)
                              break;
                      }
                  }
      
                  private void OnThreadProcess()
                  {
                      if (_socket != null)
                      {
                          EndPoint ep = new IPEndPoint(IPAddress.Any, 0) as EndPoint;
                          try
                          {
                              _bytesReceived = _socket.ReceiveFrom(_byteData, _byteData.Length, SocketFlags.None, ref ep);
                              if (_bytesReceived > 0)
                              {
                                  _packetCounter++;
                                  if (_packetCounter >= 300) _killThread = true;
      
                                  _sbTextOut.AppendLine(string.Format("{0} : {1} {2} {3} {4} {5} {6} {7}", DateTime.Now.ToString("H:mm:ss.ffffff"), _packetCounter, _byteData[0], _byteData[1], _byteData[2], _byteData[3], _byteData[4], _byteData[5]));
                                  Dispatcher.Invoke(new Action(() =>
                                  {
                                      textBlock1.Text = _sbTextOut.ToString(); 
                                  }));
                              }
                          }
                          catch (Exception ex)
                          {
                              Console.Error.WriteLine(ex.Message);
                          }
                      }
                  }
      
                  private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
                  {
                      _killThread = true;
                  }
              }
          }
      

1 个答案:

答案 0 :(得分:0)

不幸的是,代码现在在所有配置中都以慢速捕获。我再也无法获得300 /秒的数据包捕获。它现在运行/捕获大约2-3 /秒。是的,我使用相同的源代码。我确信这个问题与vshosts有关(感谢Kris)。不幸的是,我仍然不知道如何重新创建更高的捕获率,而较慢的速率并不足以使用。显然它是可能的,因为它一整天都在快速运行......直到现在。谢谢大家的帮助。