繁体   English   中英

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

[英]C# WPF code runs faster in Visual Studio than from console, and slower from another folder

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

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

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

问题/问题

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

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

因此,如果代码从原始文件夹中的Visual Studio(x86 Release)运行,则代码仅执行得很快。

我试过的其他事情:

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

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;
            }
        }
    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM