Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WP8:Dispatcher.BeginInvoke不';不能在UI线程上执行操作_C#_Multithreading_Windows Phone 8_Monogame_Begininvoke - Fatal编程技术网

C# WP8:Dispatcher.BeginInvoke不';不能在UI线程上执行操作

C# WP8:Dispatcher.BeginInvoke不';不能在UI线程上执行操作,c#,multithreading,windows-phone-8,monogame,begininvoke,C#,Multithreading,Windows Phone 8,Monogame,Begininvoke,我正在使用MonoGame将WindowsPhone7游戏移植到WindowsPhone8。我的游戏使用Texture2D.FromStream从Internet加载图片,一旦它还没有在MonoGame中实现,我就尝试建议的解决方法:在UI线程中使用BitmapImage加载图片 代码如下: Texture2D result = null; EventWaitHandle Wait = new AutoResetEvent(false);

我正在使用MonoGame将WindowsPhone7游戏移植到WindowsPhone8。我的游戏使用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();
            });
Texture2D结果=null;
EventWaitHandle Wait=新建自动重置事件(false);
Deployment.Current.Dispatcher.BeginInvoke(()=>
{
BitmapImage=新的BitmapImage();
image.SetSource(流);
WriteableBitmap writeImage=新的WriteableBitmap(图像);
var指数=0;
var pixels=新字节[writeImage.PixelWidth*writeImage.PixelHeight*4];
对于(var h=0;h>16&0xFF);
像素[wIndex++]=(字节)(像素>>8&0xFF);
像素[wIndex++]=(字节)(像素>>0&0xFF);
像素[wIndex++]=(字节)(像素>>24&0xFF);
}
结果=新纹理2D(graphicsDevice、writeImage.PixelWidth、writeImage.PixelHeight);
结果。设置数据(像素);
等等,Set();
});
理论上一切都好。但不知何故,动作代码从未被调用。 我在非ui工作线程中调用BeginInvoke,Deployment.Current.Dispatcher不为null并提供ui线程调度程序。 游戏是WP8项目,由VS2012的MonoGame模板制作而成。 我试图获取并保存到主线程(游戏构造函数)中的静态变量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);
}
SynchronizationContext uiThread=Hub.SyncContext//在主线程中设置(游戏构造函数)
var waitHandle=新对象();
锁(等待手柄)
{
uiThread.Post(=>
{
锁(等待手柄)
{
BitmapImage=新的BitmapImage();
image.SetSource(流);
WriteableBitmap writeImage=新的WriteableBitmap(图像);
var指数=0;
var pixels=新字节[writeImage.PixelWidth*writeImage.PixelHeight*4];
对于(var h=0;h>16&0xFF);
像素[wIndex++]=(字节)(像素>>8&0xFF);
像素[wIndex++]=(字节)(像素>>0&0xFF);
像素[wIndex++]=(字节)(像素>>24&0xFF);
}
结果=新纹理2D(graphicsDevice、writeImage.PixelWidth、writeImage.PixelHeight);
结果。设置数据(像素);
监视器。脉冲(waitHandle);
}
},空);
Monitor.Wait(waitHandle);
}
但同样不走运:执行在等待时停止,操作代码中的断点永远不会被触发

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

我使用此库解决了这个问题: 这个fork完全适用于WP8,如果您删除了所有Contract.Requires like语句,它的效果非常好。 这是我的纹理2D.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
    }
public static Texture2D TextureFromStream(图形设备图形设备、流媒体、字符串dbg_nm)
{           
#如果WP8
字节[]b=新字节[4];
读取(b,0,4);
stream.Seek(0,SeekOrigin.Begin);
int stream_type=getStreamType(b,0);
Texture2D result=null;
如果(流_类型==1 ||流_类型==0)
{
var image=new ExtendedImage();
如果(流类型==0)
新的JPEGDecoderNo().Decode(图像、流);
其他的
{
尝试
{
新PngDecoder().解码(图像、流);
}
catch(System.Exception-ex)
{
Debug.WriteLine(“错误读取“+dbg_nm+”:“+ex.Message”);
}                   
}
var Colors=新颜色[image.Pixels.Length/4];
对于(变量i=0;i
在游戏构造器中:

    #if WP8
    Decoders.AddDecoder<PngDecoder>();
    Decoders.AddDecoder<JpegDecoder>();
    #endif
#如果WP8
AddDecoder();
AddDecoder();
#恩迪夫
这实际上是一个解决办法。但在我的情况下,这种方式比使用uith的MS BitmaImage要好得多