2012-04-17 65 views
0

我在這裏以下答案:缺少網絡發送/接收

Calculating Bandwidth

而且他說的那樣實現一切。我的顯示器被初始化像這樣:

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

我可以corrently看到Misc.GetInstanceName()返回 「MyProcessName [ID]」。但是,我一直在獲取例外情況,即該實例不存在於指定的類別中。

我的理解是,發送/接收的網絡類別不會在您實際發送或接收之前創建。

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.net> 
     <settings> 
      <performanceCounters enabled="true" /> 
     </settings> 
    </system.net> 
</configuration> 

爲什麼我仍然得到一個錯誤:

像這樣的答案描述我已經添加了的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; 
    } 

    /// <summary> 
    /// Returns the amount of data sent from the current application in MB 
    /// </summary> 
    /// <returns></returns> 
    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); 
    } 

    /// <summary> 
    /// Returns an assembly name 
    /// </summary> 
    /// <returns></returns> 
    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; 
    } 
} 

編輯:我從窗戶打開資源監視器,看看是什麼問題。計數器不會啓動,儘管app.config設置爲這樣做。

這是我所看到的(在此之前和之後我的應用程序發送的網絡活動)

enter image description here

和名字是不是我的方法是返回。我的方法返回「SuperScraper [appId]」,而在資源中它被稱爲「Superscraper.vshost.exe」。

所以我現在有兩個問題:

-My計數器沒有啓動應用程序啓動時 -The的名字是目前存在的

+0

你能顯示堆棧跟蹤嗎?什麼是雜項? [Here](http://pastebin.com/f371375d6)是全部代碼,只是複製粘貼。 – Reniuz 2012-04-17 09:36:36

+0

雜項只是我使用的圖書館。我會發布堆棧跟蹤。 – TheGateKeeper 2012-04-17 09:40:23

+1

調用堆棧非常空。它所做的就是從我的庫中調用該方法。問題是因爲代碼位於庫中而不是我的主應用程序中?我的代碼非常像你的代碼。 – TheGateKeeper 2012-04-17 09:42:07

回答

1

好吧,我想你的例子。我也expierenced該計數器didnt性能監視器中顯示,但它確實我改變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); 

計數器看起來像開始工作。

下面是引用如何add and remove counter instance

想想也刪除(netSentCounter.RemoveInstance())計數器完成使用它後。

+0

我真的不知道它有什麼問題。我已經設法使用您的代碼創建它,但它永遠不會返回任何內容。它所做的就是讓我回到0。如果我不自己創建它,它確實會返回值。你認爲這是因爲'netSentCounter.RawValue = 0;'?你的回報值了嗎? – TheGateKeeper 2012-04-17 13:31:50

+0

以及我沒有測試過,我只是想弄清楚爲什麼你會得到錯誤。 – Reniuz 2012-04-17 14:06:52

+0

名稱匹配,我創建它在同一個地方,但值永遠不會改變。如果我不創建它並讓它自己創建(例如通過發送請求),它會報告值。你可以測試你是否得到相同的行爲? – TheGateKeeper 2012-04-17 16:30:20

3

好吧,我終於明白了。列出的步驟Calculating Bandwidth似乎已過時,並且不再適用於.Net 4.

我將解釋整個過程,以便您可以做到這一點。

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

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.net> 
     <settings> 
      <performanceCounters enabled="true" /> 
     </settings> 
    </system.net> 
</configuration> 

.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]

希望這樣可以節省別人的時間!

+0

Upvote for「在.Net 4.0中,它告訴它在使用時創建計數器」。謝謝:) – Henners 2014-11-10 12:21:13

+0

順便說一句,這裏是獲取.NET性能計數器的完整實例名稱的正確方法:http://stackoverflow.com/questions/10196432/getting-the-clr-id – Funbit 2015-03-06 16:26:25