0

私はここで答えに従っています:

帯域幅の計算

そして彼が言ったようにすべてを実装しました。私のモニターは次のように初期化されます:

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

Misc.GetInstanceName()「MyProcessName[id]」を返すことが正しくわかります。ただし、インスタンスが指定されたカテゴリに存在しないという例外が発生し続けます。

私の理解では、ネット送受信のカテゴリは、実際に送受信するまで作成されません。

私は次のように答えで説明されているようにapp.configを追加しました:

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

それでもエラーが発生するのはなぜですか?

これが私の監視コードです:

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が開始するように設定されているにもかかわらず、カウンターが開始されていません。

これが私が見るものです(これは私のアプリケーションがネットワークアクティビティを送信する前後です)

ここに画像の説明を入力してください

そして、その名前は私のメソッドが返すものではありません。私のメソッドは「SuperScraper[appId]」を返しますが、リソース内では「Superscraper.vshost.exe」と呼ばれます。

だから私は今2つの問題を抱えています:

-アプリの起動時にカウンターが起動しません-名前はdiffernetです

4

2 に答える 2

4

わかりました、私はついにそれを理解しました。帯域幅の計算に記載されている手順は時代遅れのようで、.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 では、使用時にカウンターを作成するように指示します。すなわち。これを設定しないと、カウンターは作成されません。

今、ここで私はほとんどの時間を無駄にしました。自然に作成された場合と同じ名前のパフォーマンス カウンターを作成すると、値が得られるという誤った仮定の下にありました。ただし、これは実際のカウンターが表示されないようにするだけです。

これを行う:

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

最後に 1 点。インスタンス名は ではなくなりましApplicationName[appId]た。今は次のとおりです。

[ApplicationName].exe_p_r_ad [appId]_ [the CLR id hosting your application]_[ApplicationDomain]

これが誰かの時間を節約することを願っています!!

于 2012-04-17T16:44:30.560 に答える
2

わかりました私はあなたの例を試しました。また、カウンターがパフォーマンス モニターに表示されないことも経験しましたが、プロパティを変更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()使い終わったら、( ) カウンターを削除することも検討してください。

于 2012-04-17T12:52:45.983 に答える