gpt4 book ai didi

c# - WP8 : Dispatcher. BeginInvoke 不在 UI 线程上执行操作

转载 作者:行者123 更新时间:2023-12-03 13:20:03 24 4
gpt4 key购买 nike

我正在使用 MonoGame 将 Windows Phone 7 游戏移植到 Windows Phone 8。我的游戏使用 Texture2D.FromStream 从 Internet 加载图片,一旦它尚未在 MonoGame 中实现,我正在尝试建议的解决方法:在 UI 线程中加载带有 BitmapImage 的图片。

这是代码:

            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();
});

理论上一切正常。但不知何故, Action 代码永远不会被调用。
我在非ui工作线程中调用BeginInvoke,Deployment.Current.Dispatcher不为null并提供ui-thread调度程序。
游戏是由MonoGame模板为VS2012制作的WP8项目。
我试图在主线程(游戏构造函数)中获取并保存到静态变量调度程序和 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);
}

但是再次没有运气:执行在等待时停止,并且永远不会触发 Action 代码中的断点。

更新:我刚刚添加了带有一个日志的简单代码来示例 MonoGame 项目。
如果我等待 AutoResetEvent,我永远不会看到任何日志。当我删除 are.WaitOne() Action 开始工作。我已将其替换为 are.WaitOne(1000) 并开始按预期工作(为什么?)。
但是图像加载仍然没有运气。当我在 are.WaitOne() 中等待时,似乎有什么东西阻止了主线程运行。

最佳答案

我通过使用这个库解决了问题:
https://github.com/Taggersoft/ImageTools
这个 fork 完全适用于 WP8,如果你删除所有 Contract.Requires 类似的语句,它会非常有效。
这是我的 Texture2d.FromStream 替换:

        public static Texture2D TextureFromStream(GraphicsDevice graphicsDevice, Stream stream, String dbg_nm)
{
#if WP8
byte [] b = new byte[4];
stream.Read(b, 0, 4);
stream.Seek(0, SeekOrigin.Begin);
int stream_type = getStreamType(b, 0);
Texture2D result = null;

if (stream_type == 1 || stream_type == 0)
{
var image = new ExtendedImage();
if (stream_type == 0)
new JpegDecoderNano().Decode(image, stream);
else
{
try
{
new PngDecoder().Decode(image, stream);
}
catch (System.Exception ex)
{
Debug.WriteLine("Error reading " + dbg_nm + ":" + ex.Message);
}
}

var Colors = new Color[image.Pixels.Length / 4];
for (var i = 0; i < image.Pixels.Length / 4; i++)
{
Color unpackedColor = new Color();
unpackedColor.R = (byte)(image.Pixels[i * 4 + 0]);
unpackedColor.G = (byte)(image.Pixels[i * 4 + 1]);
unpackedColor.B = (byte)(image.Pixels[i * 4 + 2]);
unpackedColor.A = (byte)(image.Pixels[i * 4 + 3]);
Colors[i] = unpackedColor;
}
Texture2D texture2D = new Texture2D(graphicsDevice, image.PixelWidth, image.PixelHeight);
texture2D.SetData(Colors);
result = texture2D;
}

return result;

#else
return Texture2D.FromStream(graphicsDevice, stream);
#endif
}

在游戏构造函数中:
    #if WP8
Decoders.AddDecoder<PngDecoder>();
Decoders.AddDecoder<JpegDecoder>();
#endif

这实际上是一种解决方法。但在我的情况下,这种方式比使用 uithread 中的 MS BitmapImage 要好得多。

关于c# - WP8 : Dispatcher. BeginInvoke 不在 UI 线程上执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21938430/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com