私はネイティブdllのラッパーである第三者のライブラリを使用します。ライブラリにはタイプ,にはいくつかのプロパティがあり、IntPtr Data()
メソッドがあります。IDisposable
も実装されていますが、正しく実装されているかどうかはわかりません。アンマネージドリソースを使用して作業する
TCP接続から多くのを取得し、PictureBox
の映画として表示します。
私は 'XImage'をSystem.Drawing.Image
に変換し、PictureBox
で表示しましたが、私はAccessViolationException
を得ました。
Frame
というのラッパーを作った。
public class Frame : IDisposable
{
public uint size { get; private set; }
private Image image;
public XImage XImage { get; set; }
public Image Image { get { return image ?? (image = GetBitmap(this.XImage)); } }
public DateTime Time { get; set; }
public Frame(XImage xImage)
{
this.XImage = xImage;
this.size = XImage.ImageBufferSize();
GC.AddMemoryPressure(size);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Frame()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
image.Dispose();
}
catch { }
finally
{
image = null;
}
try
{
MImage.Dispose();
}
catch { }
finally { XImage = null; }
}
GC.RemoveMemoryPressure(size);
}
}
と私はAccessViolationException
を解決Frame
への参照を扱うこともできます。 今私はビジュアルスタジオ(F5 - 起動デバッグ)からプログラムを実行すると、すべての問題はありませんが、.exe
ファイル(またはctrl + F5 - デバッグなしで起動)からメモリ使用量が大きくなっていますOutOfMemoryException
を取得するまでは大きくなります(Biuld Configuration:Release-X86)。私は何をすべきか ?
---- EDIT ----
私はGC.AddMemoryPressure
かGC.RemoveMemoryPressure
がちょうどより頻繁に実行するためにガベージコレクションを作ることがわかったと、私の問題は、私はへのハンドルを持っている小さなオブジェクトを持っているということになりました大規模な管理されていないメモリであり、GCはこれらの小さなオブジェクトを収集していません。そう
---- EDIT ----
GC.Collect
を呼び出すと、実行時に問題を解決します、私はタイマーを設定し、定期的にGC.Collect
を呼ぶが、それは短い期間のためのアプリケーションのフリーズを行い、私はこのアプローチを使いたくありません。
あなたはそれを解決していない、あなたはすべての例外をキャッチしてそれを隠した。後で問題を解決することは避けられません。このような問題を引き起こすライブラリを捨てなさい。 –
'Dispose()'メソッドですべての例外を呑み込んでいるだけです。 XImageが実際にうまく処理できなかった可能性があります。 – angelsl
@HansPassant:私は図書館が大丈夫だと思います。私はタイマーを設定し、GC.Collect()を30秒ごとに呼び出し、 'OutOfMemoryException'を解決しますが、これは良いアプローチではありません。デバッガでの実行がデバッガなしでの実行と異なる理由 – HPT