MonoGame을 사용하여 Windows Phone 7 게임을 Windows Phone 8에 이식하고 있습니다. 내 게임은 인터넷에서 사진을로드하려면 Texture2D.FromStream을 사용하고, 아직 MonoGame에 구현되지 않는 한 제안 방안을 시도하고 있습니다. UI 스레드에서 BitmapImage로 그림을로드하고 있습니다.WP8 : Dispatcher.BeginInvoke가 UI 스레드에서 작업을 실행하지 않습니다.
Texture2D result = null;
EventWaitHandle Wait = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
BitmapImage image = new BitmapImage();
image.SetSource(stream);
WriteableBitmap writeImage = new WriteableBitmap(image);
var index = 0;
var pixels = new byte[writeImage.PixelWidth * writeImage.PixelHeight * 4];
for (var h = 0; h < writeImage.PixelHeight; h++)
for (var w = 0; w < writeImage.PixelWidth; w++)
{
var pixel = writeImage.Pixels[index++];
var wIndex = w * 4 + h * writeImage.PixelWidth * 4;
pixels[wIndex++] = (byte)(pixel >> 16 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 8 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 0 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 24 & 0xFF);
}
result = new Texture2D(graphicsDevice, writeImage.PixelWidth, writeImage.PixelHeight);
result.SetData(pixels);
Wait.Set();
});
이론적으로 모든 것이 괜찮 : 여기
는 코드입니다. 그러나 어떻게 든 액션 코드는 호출되지 않습니다. 비 사용자 작업자 스레드에서 BeginInvoke를 호출 할 때 Deployment.Current.Dispatcher가 null이 아니며 ui-thread 디스패처를 제공합니다. 게임은 VS2012 용 MonoGame 템플릿으로 만든 WP8 프로젝트입니다. 주 스레드 (게임 생성자)의 정적 변수 dispatcher 및 SynchronizationContext에 가져 와서 그 변수가 UI 스레드와 정확히 일치하는지 확인하려고 시도했지만 도움이되지 않습니다.SynchronizationContext uiThread = Hub.SyncContext;//set in main thread (Game constructor)
var waitHandle = new object();
lock (waitHandle)
{
uiThread.Post(_ =>
{
lock (waitHandle)
{
BitmapImage image = new BitmapImage();
image.SetSource(stream);
WriteableBitmap writeImage = new WriteableBitmap(image);
var index = 0;
var pixels = new byte[writeImage.PixelWidth * writeImage.PixelHeight * 4];
for (var h = 0; h < writeImage.PixelHeight; h++)
for (var w = 0; w < writeImage.PixelWidth; w++)
{
var pixel = writeImage.Pixels[index++];
var wIndex = w * 4 + h * writeImage.PixelWidth * 4;
pixels[wIndex++] = (byte)(pixel >> 16 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 8 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 0 & 0xFF);
pixels[wIndex++] = (byte)(pixel >> 24 & 0xFF);
}
result = new Texture2D(graphicsDevice, writeImage.PixelWidth, writeImage.PixelHeight);
result.SetData(pixels);
Monitor.Pulse(waitHandle);
}
}, null);
Monitor.Wait(waitHandle);
}
그러나 다시 행운 : 실행이 발사되지 않습니다 액션 코드의 대기 및 중단 점에서 중지
또한 나는 그런 코드를 시도했다.업데이트 : 샘플 코드 MonoGame 프로젝트에 단 하나의 로그로 간단한 코드를 추가했습니다. AutoResetEvent를 기다리는 경우 로그가 표시되지 않습니다. 내가 are.WaitOne() 작업을 제거하면 작동하기 시작했다. 나는 그것들로 바꿨다. 와이토 원 (1000)과 예상대로 일하기 시작한다. (왜?). 이미지 로딩과 관련하여 여전히 운이 없습니다. 대기중인 동안 메인 스레드가 실행되는 것을 막아주는 것 같습니다 .WaitOne().
UI 스레드 (예 :로드 또는 시작 등)에서 Deployment.Current.Dispatcher 값을 가져 와서 저장하면 차이가 있습니까? –
@Tertium, 왜'Post'와'Monitor.Pulse'를 쓰는 대신'uiThread.Send'를 사용하지 않으시겠습니까? – Noseratio
@PeterRitchie 아니, 이건 도움이 안된다 – Tertium