• SilverLight系列——Image控件的BUG


          近日在做silverlight开发时,发现只要运行开发的程序,无论是否开启调试状态,IE进程占用CPU始终在90%上下,然而在展示某些窗体时又很正常,这可是个大件事啊,等交到客户手里看到这CPU使用率还不得被批死。经过多方排查后发现,造成CPU高占用率的窗体都有一个共同点:使用了Image控件但都没能展示出图片(赋值了图片地址给Image.Source属性,但实际上图片不存在),难道这就是罪魁祸首?

          Google了一通,找到了一篇帖子:

          Binding silverlight image control to an empty BitmapImage causes high cpu utilization

          这是帖子中两个人的描述:

          When a silverlight image control is bound to an empty BitmapImage, sustained high CPU utilization occurs (15 - 25% on my machine). When source is set to null or to a valid image, cpu use drops to idle.

          If this.ImageUrl.Value is null the SL app takes up close to 100% CPU on one core as long as it is visible on screen. Minimizing the window brings CPU down to 0%

          下面是Microsoft给的回复:

          Thank you for reporting this issue.
          We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

          还真是有问题啊!这微软也是,如此常用的控件还搞出这档子事。埋怨无用,还是想怎么解决吧。我想了一个办法,不直接为Image.Source赋值,而是通过一些代码,尝试根据图片路径去请求文件流,如果成功,则实例化一个BitmapImage赋值给Image.Source,否则,将Image.Source设为null。代码:

        public static class Img
        {
            public static readonly DependencyProperty UriProperty;
    
            static Img()
            {
                UriProperty = DependencyProperty.RegisterAttached("Uri", typeof(Uri), typeof(Img), 
                     new PropertyMetadata(null, UriPropertyChanged));
            }
    
            public static Uri GetUri(Image image)
            {
                return (Uri)image.GetValue(UriProperty);
            }
    
            public static void SetUri(Image image, Uri uri)
            {
                image.SetValue(UriProperty, uri);
            }
    
            static void UriPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                Image image = sender as Image;
                Uri uri = e.NewValue as Uri;
                TrySetImageSourceByUri(image, uri);
            }
    
            static void TrySetImageSourceByUri(Image image, Uri uri)
            {
                if (string.IsNullOrEmpty(uri.OriginalString))
                {
                    image.SetValue(Image.SourceProperty, null);
                    return;
                }
    
                WebClient client = new System.Net.WebClient();
                client.OpenReadCompleted += (sender, e) =>
                {
                    if (e.Error == null)
                    {
                        BitmapImage bitImg = new BitmapImage();
                        bitImg.SetSource(e.Result);
                        image.Source = bitImg;
                    }
                    else
                        image.SetValue(Image.SourceProperty, null);
                };
                client.OpenReadAsync(uri);
            }
        }
     
        类似以下的使用方式:
        <Image local:Img.Uri=”Images/TestPic.jpg” />
     
        需要注意的:
        1、上述的"Images/TestPic.jpg”,实际地址为:ClientBin/Images/TestPic.jpg,若直接设置到Source属性,需写成"/Images/TestPic.jpg”;
        2、上述方法不支持XAP包内地址,类似于:"/VDP.SL.Controls;component/Images/TestPic.jpg”,个人也不推荐把图片放到silverlight项目下,
           因为会把XAP包撑大,用于工具栏上的小图标可以视情形而定;
     
    2011-9-19日,又发现了Image.Source可能引发的一种错误现象:
    当我打开一个silverlight窗体时,浏览器提示以下脚本错误:
    消息: Unhandled Error in Silverlight Application 
    Code: 4009   
    Category: ManagedRuntimeError      
    Message: 元素已经是另一个元素的子元素。
    这个错误没办法捕捉,因为根本不到VS的调试器里,从脚本错误中也完全无法得知发生错误的位置。后面只能用最笨的办法,一个一个控件注释,一遍遍尝试,终于发现是Image惹的祸,把Image中的
    Source="{Binding Path=[PositiveImgRUL]}" 删掉就和谐了。当然,我会换上:vdp:Img.Uri="{Binding Path=[PositiveImgRUL]}"
     
  • 相关阅读:
    C#开发ActiveX可行性研究 简单飞扬
    有几件事情 简单飞扬
    1 简单飞扬
    宁静 会一直存在么 简单飞扬
    java 项目中遇到的错误 简单飞扬
    开发线程安全的Spring Web应用(转) 简单飞扬
    p2p网站即时通信 简单飞扬
    游戏外挂原理和技术分析(关于魔力宝贝) 简单飞扬
    关于java使用javacomm20win32实践总结 (转) 简单飞扬
    Java 串口编程 简单飞扬
  • 原文地址:https://www.cnblogs.com/sdlfx/p/2137373.html
Copyright © 2020-2023  润新知