2012-08-16 8 views
5

Im을 작성하면 Label이고, 때로는 .DrawToBitmap()을 사용합니다. 그 이유를 잘 모릅니다 만, 필자는 잠시 동안 내 프로그램을 실행 (종종 .DrawToBitmap()를 호출) 후 나는 예외를 얻을 :이 자주DrawToBitmap - System.ArgumentException : 매개 변수가 유효하지 않습니다.

System.ArgumentException: Parameter is not valid. 
    at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format) 
    at System.Drawing.Bitmap..ctor(Int32 width, Int32 height) 

은 어떻게 든 내가 호출 할 수 없습니다이 기능을. 나는 근본적으로 이것을 시도 할 경우

while(true) 
{ 

    System.Windows.Forms.Label label = new Label(); 

    label.Font = new Font("Arial", 20); 
    label.Text = "test"; 

    try 
    { 
    Bitmap image = new Bitmap(300, 500); 
    label.DrawToBitmap(image, label.ClientRectangle); 
    } 
    catch (Exception e) 
    { 
    Console.WriteLine(e); 
    } 
} 

을 나는 5 ~ 6 초 (1,000에서 2,000 사이 전화)을 제외한 후 얻었다. 문제가 무엇입니까? 이것을 피하는 방법?

편집 : Dispose()과 함께 아이디어를 주셔서 감사합니다. 어쨌든 label에 사용하면 모든 것이 완벽하게 작동합니다. 비트 맵에서 사용하지 않더라도 괜찮습니다. 두 답변 모두 훌륭합니다. (

답변

6

그래서 오류 메시지는 GDI +의 심층에서 발생하며 개의 많은 이유로 나타납니다. 코드에 눈부신 문제가 하나 있습니다. 즉 그러나 후보 :..

label.Font = new Font("Arial", 20); 

Font 객체가 IDisposable를 구현하고 Dispose()를 호출 꽉 루프에서 그들을 많이 생성하지 않으며 결코 동일이 비트 맵 자체에 간다 나는 GDI가 부족합니다 내기 것 리소스.

It 's har d 당신의 코드를 그대로 이해하십시오. 본질적으로 아무 것도 만들지 않고 단지 FontBitmap 개체를 생성하므로 각 선언을 각각 using 문으로 래핑하도록 제안 할 수는 없습니다. 그건 제외하고, 당신이 신속하게 연속적으로 그들을 처리하지 않고도 GDI 객체 톤을 만들 때 당신은 결국이 문제에 부딪 힐 것이다.

이러한 개체가 유효해야하는 경우 나중에 Dispose()을 호출하여 가능한 한 적시에 기본 리소스를 릴리스해야합니다 (최종 사용자가 대신이 작업을 수행하지만, 그것을 기다리지 말라.) 그들은 로컬 객체는 다음 그래서 Dispose()가 블록 종료 될 때 호출됩니다 using 성명을 포장하는 경우 :

using(var b = new Bitmap(w, h)) 
{ 
    // use 'b' for whatever 
} // b.Dispose() is called for you 
+0

안녕하세요. 처음에는 (Bitmap ...) => 전혀 변경하지 않았습니다. 그러나 각 호출이 끝날 때 label.Dispose()를 사용할 때마다 괜찮았다. :) 감사합니다. 30.000 호출로 테스트 했으므로 지금은 괜찮다고 생각합니다. without label.Dispose() 1000-2000 호출 후에 예외가 발생합니다. 라벨을 폐기해야한다고 생각한 적이 없어. – miri

+0

@miri : @HansPassant처럼 : 레이블을 삭제하면 예외가 발생할 것이라고 생각했을 것입니다. 필자는 글꼴과 비트 맵을 'using'블록으로 묶어야한다고 생각한다. 라벨이 어떻게 다른 방식으로 사용되는지 보지 않고 라벨 폐기 방법을 벗어날 수있는 방법을 모르겠습니다. – IAbstract

4

GDI + 예외는 매우 가난, 그들은 종종 아니라 실제 문제에 대한 설명이 없습니다. 이 경우에는 "비트 맵이 너무 큽니다"라는 의미입니다. 아직도 잘 설명하지 못하는데 실제로 관리되지 않는 메모리가 부족합니다. 비트 맵이 너무 커서 사용할 수있는 메모리 양에 맞지 않습니다.

비트 맵에서 Dispose() 메서드를 호출하지 않기 때문에. 당신은 종종 문제를 알지 못해서 그 일에 몰두할 수 있습니다. 그러나 비트 맵이 아니라 가비지 수집 메모리는 적지 ​​만 관리되지 않는 메모리는 많이 사용하는 클래스입니다. 파이널 라이저가 관리되지 않는 메모리를 해제 할 수있을만큼 빨리 가비지 수집기를 트리거하지 않습니다.

코드 조각은 이해가되지 않지만,이 예외 피하기 위해 같은 당신은 그것을 쓰는 것 :

using (Bitmap image = new Bitmap(300, 500)) { 
    label.DrawToBitmap(image, label.ClientRectangle); 
} 
+1

저는 심각하게 GDI 오류 메시지를 심각하게 싫어합니다 ... 메시지 자체를 쓸모 없게 만드는 문제를 진단하는 데 경험이 필요합니다. –

+0

아이디어에 감사드립니다! Dispose()는 훌륭하지만 어떻게 든 라벨에 사용해야합니다. – miri

+0

글쎄, 아니, 확실히 당신이 레이블을 처분하고 싶지 않아, 그게 사라지고 코드가 충돌하게 만들 것입니다. 비트 맵을 삭제합니다. –

관련 문제