发送/接收的网络丢失

我在这里听到了答案:

计算带宽

并实施了他所说的一切。 我的监视器初始化如下:

netSentCounter.CategoryName = ".NET CLR Networking"; netSentCounter.CounterName = "Bytes Sent"; netSentCounter.InstanceName = Misc.GetInstanceName(); netSentCounter.ReadOnly = true; 

我可以正确地看到Misc.GetInstanceName()返回“MyProcessName [id]”。 但是,我不断得到实例在指定类别中不存在的exception。

我的理解是,在您实际发送或接收之前,不会创建网络发送/接收的类别。

我按照答案中的说明添加了app.config,如下所示:

         

为什么我仍然会收到错误?

这是我的监控代码:

 public static class Monitoring { private static PerformanceCounter netSentCounter = new PerformanceCounter(); //Static constructor static Monitoring() { netSentCounter.CategoryName = ".NET CLR Networking"; netSentCounter.CounterName = "Bytes Sent"; netSentCounter.InstanceName = Misc.GetInstanceName(); netSentCounter.ReadOnly = true; } ///  /// Returns the amount of data sent from the current application in MB ///  ///  public static float getNetSent() { return (float)netSentCounter.NextValue() / 1048576; //Convert to from Bytes to MB } } 

我的杂项课程:

 public static class Misc { //Returns an instance name internal static string GetInstanceName() { // Used Reflector to find the correct formatting: string assemblyName = GetAssemblyName(); if ((assemblyName == null) || (assemblyName.Length == 0)) { assemblyName = AppDomain.CurrentDomain.FriendlyName; } StringBuilder builder = new StringBuilder(assemblyName); for (int i = 0; i < builder.Length; i++) { switch (builder[i]) { case '/': case '\\': case '#': builder[i] = '_'; break; case '(': builder[i] = '['; break; case ')': builder[i] = ']'; break; } } return string.Format(CultureInfo.CurrentCulture, "{0}[{1}]", builder.ToString(), Process.GetCurrentProcess().Id); } ///  /// Returns an assembly name ///  ///  internal static string GetAssemblyName() { string str = null; Assembly entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly != null) { AssemblyName name = entryAssembly.GetName(); if (name != null) { str = name.Name; } } return str; } } 

编辑:我已从Windows打开资源监视器以查看问题所在。 虽然设置了app.config,但计数器仍未启动。

这是我看到的(这是我的应用程序发送网络活动之前和之后)

在此处输入图像描述

并且名称不是我的方法返回的名称。 我的方法返回“SuperScraper [appId]”,而在资源中它被称为“Superscraper.vshost.exe”。

所以我现在有两个问题:

– 我的计数器没有在应用启动时启动 – 名称是不同的

好的,我终于明白了。 列出的计算带宽似乎已过时,不再适用于.Net 4。

我将解释整个过程,所以你也可以这样做。

首先,您需要将其添加到您的app.config:

         

在.Net 4.0之前,这使得应用程序在启动时创建计数器(例如,在应用程序发送请求时创建网络计数器)。 在.Net 4.0中,这告诉它在使用它们时创建计数器。 IE浏览器。 如果你没有设置这个,就不会创建任何计数器。

现在这是我浪费大部分时间的地方。 我错误的假设是,如果你创建一个具有与自然创建时相同名称的性能计数器,你将得到这些值。 然而,所有这一切都阻止了真正的计数器出现。

这样做:

 //In .Net 4.0 the category is called .NET CLR Networking 4.0.0.0 and not .NET CLR Networking netSentCounter.CategoryName = ".NET CLR Networking 4.0.0.0"; netSentCounter.CounterName = "Bytes Sent"; netSentCounter.InstanceName = Misc.GetInstanceName(); netSentCounter.ReadOnly = false; //<== netSentCounter.RawValue = 0; //<== 

只需阻止真正的计数器。

你需要做的是以自然的方式启动它。 执行此操作的最佳方法是在应用程序启动时简单地发送欺骗请求,然后使用以下方式“监听”性能计数器:

 //Send spoof request here netSentCounter.CategoryName = ".NET CLR Networking 4.0.0.0"; netSentCounter.CounterName = "Bytes Sent"; netSentCounter.InstanceName = Misc.GetInstanceName(); netSentCounter.ReadOnly = true; 

最后一点。 实例名称不再是ApplicationName[appId] 。 现在它是:

[ApplicationName] .exe_p [appId] _r [the CLR id hosting your application] _ad [ApplicationDomain]

希望这能节省时间!

好的,我试过你的例子。 我还看到了在性能监视器中没有显示的计数器,但是在我更改了ReadOnly并设置了RawValue属性之后它就完成了:

 netSentCounter.CategoryName = ".NET CLR Networking"; netSentCounter.CounterName = "Bytes Sent"; netSentCounter.InstanceName = Misc.GetInstanceName(); netSentCounter.ReadOnly = false; //<== netSentCounter.RawValue = 0; //<== 

在我的例子中,我发现性能监视器中的实例名称采用以下格式: myapplicationname_pPID

所以在我更改了GetInstanceName方法行之后

 return string.Format(CultureInfo.CurrentCulture, "{0}[{1}]", builder.ToString(), Process.GetCurrentProcess().Id); 

 return string.Format(CultureInfo.CurrentCulture, "{0}_p{1}", builder.ToString().ToLower(), //<== dont miss ToLower() Process.GetCurrentProcess().Id); 

计数器看起来像开始工作。

以下是如何添加和删​​除计数器实例的参考

在完成使用它之后,还要考虑删除( netSentCounter.RemoveInstance() )计数器。