リークをかなり追跡しましたが、自分で理解 (修正) できないようです。最初にANTSメモリプロファイラーを使用して、コードが実際にメモリをスタックしていることを確認しました。最初は 25 MB を使用していましたが、1 時間ほどで 100 MB を超えました。私がこれをコーディングしている私の友人は、実際にこの欠陥のあるプログラムを使用していて、18 GB の RAM をすべて使い果たしてしまい、メモリ不足の例外が発生しました。
リーク部分はプログラムにとって重要ではありませんが、 RefreshSessions() メソッドがなければほとんど役に立ちません。
私は、Code Project からプロジェクトVista Core Audio API Master Volume Controlを拡張してきました。
漏れそうな部分です。未使用でテストしましたが、漏れません。
更新しました:
public void RefreshSessions()
{
Marshal.ThrowExceptionForHR(_AudioSessionManager.GetSessionEnumerator(out _SessionEnum));
_Sessions.Refresh(_SessionEnum);
}
(ここからクラスコードを削除しました)
私はあまりコーディングしていないので、何か見落としているかもしれませんが、さらに詳細が必要な場合は、実際にソースをダウンロードするか、私の最善の能力に答えることができます.
(ここで不要なコードを削除)
リークは、次の単純なコンソール アプリでテストされました。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
Console.ReadKey();
int i = 0;
while (i < 10000)
{
device.AudioSessionManager.RefreshSessions();
i++;
}
Console.ReadKey();
}
}
}
更新 2
私はそれを修正したと思います。もう少し長いテストを実行する必要がありますが、少なくともメモリ使用量は安定しているようです。このアイデアは、c++ でリークの修正を見つけたダイヤラーから生まれました。
public void RefreshSessions()
{
_Sessions.Release(); //added this
IAudioSessionEnumerator _SessionEnum;
Marshal.ThrowExceptionForHR(_AudioSessionManager.GetSessionEnumerator(out _SessionEnum));
_Sessions.Refresh(_SessionEnum);
}
これは の部分ですSessionCollection
:
public void Release()
{
Marshal.ReleaseComObject(_AudioSessionEnumerator);
}
これは、提案されたコードダイヤラーとは正確には異なりますが(とにかく使用することになりました)、それでも. 彼が言ったように、これはこれを達成するための最良の方法ではないかもしれませんが、私のアプリに悪影響を及ぼさないと思われるので、私はそれを採用します.