WriteableBitmap
을 사용하여 성능에 민감한 그림이 나타나는 응용 프로그램이 있습니다. 이벤트는 WriteableBitmap
의 백 버퍼를 실제로 업데이트하기 위해 CompositionTarget.Rendering
으로 호출됩니다. MSDN 설명서에서 이벤트가 프레임 당 한 번, 컨트롤이 렌더링되기 바로 전에 발생한다는 것을 의미합니다.WriteableBitmap.Lock() 성능 문제
내가 겪고있는 문제는 WriteableBitmap의 Lock()
함수가 특히 더 큰 비트 맵 크기에서 매우 오랜 시간이 걸린다는 것입니다. 이전에 AddDirtyRegion()
에는 전체 비트 맵이 무효화되는 버그가있어서 성능이 저하되었다고 읽었습니다. 그러나, 여기서는 그렇지 않습니다. 저수준 검사의 좋은 비트에서, Lock()
은 렌더링 스레드에 쓰기 위해 비트 맵의 백 버퍼를 여는 것으로 보입니다. 이는 내 이벤트 핸들러가 호출 될 때마다 렌더링 스레드가 준비 될 때까지 스레드를 블록해야한다는 것을 의미합니다. 이로 인해 비트 맵의 그래픽을 업데이트 할 때 눈에 띄는 지연이 발생합니다.
이미 이벤트 처리기에 TryLock()
을 사용하여 시간 초과를 추가 했으므로 오랜 시간 동안 차단되지 않고 성능이 저하됩니다. 그러나 비트 맵 업데이트 수가 많아지기 때문에 지연되는 것처럼 보입니다.
다음은 이벤트 처리기의 관련 코드로 내가하는 작업을 정확하게 보여줍니다. UpdatePixels()
기능은 사용하지 않는 것이 기록 된 잠재적 AddDirtyRect()
도청 :
void updateBitmap(object sender, EventArgs e)
{
if (!form.ResizingWindow)
{
// Lock and unlock are important... Make sure to keep them outside of the loop for performance reasons.
if (canvasUpdates.Count > 0)
{
//bool locked = scaledDrawingMap.TryLock(bitmapLockDuration);
scaledDrawingMap.Lock();
//if (locked)
//{
unsafe
{
int* pixData = (int*)scaledDrawingMap.BackBuffer;
foreach (Int32Rect i in canvasUpdates)
{
// The graphics object isn't directly shown, so this isn't actually necessary. We do a sort of manual copy from the drawingMap, which acts similarly
// to a back buffer.
Int32Rect temp = GetValidDirtyRegion(i);
UpdatePixels(temp, pixData);
}
scaledDrawingMap.Unlock();
canvasUpdates.Clear();
}
//}
}
}
}
private unsafe void UpdatePixels(Int32Rect temp, int* pixData)
{
//int* pixData = (int*)scaledDrawingMap.BackBuffer;
// Directly copy the backbuffer into a new buffer, to use WritePixels().
var stride = temp.Width * scaledDrawingMap.Format.BitsPerPixel/8;
int[] relevantPixData = new int[stride * temp.Height];
int srcIdx = 0;
int pWidth = scaledDrawingMap.PixelWidth;
int yLess = temp.Y + temp.Height;
int xLess = temp.X + temp.Width;
for (int y = temp.Y; y < yLess; y++)
{
for (int x = temp.X; x < xLess; x++)
{
relevantPixData[srcIdx++] = pixData[y * pWidth + x];
}
}
scaledDrawingMap.WritePixels(temp, relevantPixData, stride, 0);
}
나는 WriteableBitmap으로 차단 스레드의 문제를 방지하는 방법을 알아낼 수없는 것, 내가 어떤 명백한 결함을 볼 수 없습니다 내가 작성한 코드. 어떤 도움이나 조언을 많이 주시면 감사하겠습니다.
그동안 해결책을 찾았습니까? –