2014-09-09 4 views
1

여러 개의 원수가있는 게임이 있으며 각 원마다 이동 및 그리기를 위해 자체 스레드로 실행됩니다. 원수는 패널에 그려 지므로 스레드는 패널의 그래픽에 액세스해야합니다. 나는 Lock을 사용하여 CreateGraphics 콜을 보호했고, 나는 ReleaseHdc 패널의 그래픽을 쓸 때, 어떤 인수도없이 ReleaseHdc -method를 호출하더라도 System.ArgumentException을 얻는다. 다음은 관련 코드입니다 (p 정확한 컨트롤에 정적 변수와 점으로 아래로 전달 된 패널 참조입니다) :이 오류가 발생하는 이유Graphics.ReleaseHdc() 멀티 스레드 인스턴스에서 ArgumentException 오류가 발생했습니다.

//Member region 
internal Bitmap Img = new Bitmap(Image.FromFile(@"Enemy.png"), Size); 
internal static readonly object _Lock = new object(); 

//from enemy's custom Move() method 
lock (_Lock) 
{ 
    Graphics gfx = p.CreateGraphics(); 
    gfx.DrawImage(Img, Location); 
    gfx.ReleaseHdc(); // gfx.Dispose() works here      
} 

누구 아이디어가 있습니까 및/또는 그것을 해결하는 방법, 다중 스레드 액세스를 고려하여 각 요소를 자체 스레드의 동일한 패널에 그려야합니까?

[편집]

gfx.Dispose() 대신 ReleaseHdc()의 사용 트릭을했다. 결과는 만족스럽지 않습니다. 깜박 거리는 적들과 함께 매우 불안정한 이미지를 얻었 기 때문입니다. 이것은 반복적으로 자주 그리기에 문제가 될 수 있으며 내 질문과 관련이 없습니다. 또는이 문제와 여러 스레드를 처리하는 방법 사이에 연결이 있습니까?

+0

매우 위험한 게임입니다. 그 잠금은 확실히 좋은 생각 이었지만 패널의 OnPaint() 메소드에 동일한 잠금을 설정하지 않았습니다. Panel에서 자신의 클래스를 파생시키고 OnPaint() 및 OnPaintBackground()를 재정의합니다. ReleaseHdc()를 사용하는 것은 잘못된 것이므로 대신 Dispose()를 사용해야합니다. 일할 수도 있습니다. 희망을 얻지 마십시오. –

+0

컨트롤의'Graphpics' 인스턴스를 여러 개 만들 때 충돌이 있습니까? 동시에 존재할 수있는 것은 오직 하나 일 뿐이므로 모든 스레드가 자체 스레드를 생성 할 수는 없습니까? 필자는 지금 'Panel'에서 파생 된 나의 프로그램을 재 작성하고 있지만 어쨌든 알고있는 것이 좋습니다. – Johannes

+0

여러 스레드에서 그래픽 인스턴스를 만드는 것이 좋습니다. DpiX와 같은 속성을 사용하면 좋습니다. MeasureString()과 같은 항목이 좋습니다. 실제로 화면에 페인트 칠하는 것은 위험한 게임입니다. 또한 여러 스레드가 동일한 화면 영역으로 렌더링 할 때 결국 어떤 결과가 나오는지에 대해 판단하기가 매우 어렵습니다. 최종 결과는 항상 예측할 수 없습니다. –

답변

0

gfx.ReleaseHdc()으로 전화 할 경우 gfx.GetHdc()으로 전화하지 않아도 되나요?

lock (_Lock) 
{ 
    using (var gfx = p.CreateGraphics()) 
    { 
     gfx.DrawImage(Img, Location); 
    } 
} 

나는 또한 약간의 의심이 자체 CreateGraphics()에 대한 호출을 찾을 :

나는 코드를 같이한다고 생각합니다. 내가 Graphics 개체를 오히려 그때 에 의해 만든 도면 코드를 제공 기대하고 싶습니다.

+0

이것은 여전히 ​​같은 예외를 던집니다. 그러나 Dispose()를 사용하여 위의 편집을 참조하십시오. – Johannes

+1

@Johannes하지만 위의 코드는 Dispose()를 사용하고 있습니다!그게'using'의 기능입니다 ... 그리고 같은 예외를 던지면 제가 게시 한 코드가 호출하지 않았기 때문에 문제가'ReleaseHdc()'와는 관련이 없음을 의미합니다 ... –

+0

아, 나는 그것을 인식하지 못했고'ReleaseHdc()'를 제거하지 않았다! 수동으로 Dispose를 입력하는 것과 똑같이 작동합니다. 감사합니다! 다른 의견 : Panel.CreateGraphics를 모든 스레드에 제공하는 좋은 방법이 있습니까? 나는 그것을 고정 변수를 통해 설정하고 Lock으로 보호해야한다고 생각한다. 나는 매우 간단히하기 전에 그것을 시도하고 오류가있어서, 나는 이렇게 만들려고했다. – Johannes