zoukankan      html  css  js  c++  java
  • Windowphone访问网络图片本地缓存封装CacheNetworkFile.dll的学习

    这篇博文是我根据一个缓存网络图片的demo的学习总结。

    在这个例子中调用的是CacheNetworkFile.dll中的CacheNetworkImageConvert来进行缓存网络图片的。这个CacheNetworkFile.dll里面到底是什么东东呢?

    经过神器Reflector的分析原来如此呀

    类CacheNetworkImageConvert实现了IvalueConverter接口

    View Code
    public class CacheNetworkImageConvert : IValueConverter
    {
        // Methods
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Uri uri;
            BitmapImage2 image;
            if (value != null)
            {
                uri = null;
                if (value is string)
                {
                    uri = new Uri((string) value);
                    goto Label_0030;
                }
                if (value is Uri)
                {
                    uri = (Uri) value;
                    goto Label_0030;
                }
            }
            return null;
        Label_0030:
            image = new BitmapImage2();
            CacheNetworkdFile.AddBind(uri, image, BitmapImage2.Source);//调用CacheNetWorkFile的Addbind方法来保存File
            return image;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        // Nested Types
        private class BitmapImage2 : BitmapSource
        {
            // Fields
            public static DependencyProperty Source = DependencyProperty.Register("Source", typeof(Stream), typeof(CacheNetworkImageConvert.BitmapImage2), new PropertyMetadata(null, new PropertyChangedCallback(null, (IntPtr) SourceChanged)));
    
            // Methods
            private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ((CacheNetworkImageConvert.BitmapImage2) d).SetSource((Stream) e.get_NewValue());
                ((Stream) e.get_NewValue()).Dispose();
            }
        }
    }

    这个是长长多大CacheNetworkdFile类 原作者连个注释都无有,看起来真蛋疼呀!

    View Code
    public class CacheNetworkdFile
    {
        // Fields
        private static List<propertybind> _bindlist = new List<propertybind>(10);
        private static Dictionary<Uri, CacheNetworkdFile> _cachelist = new Dictionary<Uri, CacheNetworkdFile>(10);
        private static DispatcherTimer _dispatchertimer;
        private Uri _uri;
        private const string directory = "CacheNetworkdFile";
        private EventHandler downloaderror;
        private static volatile Stack<Uri> downloadlist = new Stack<Uri>(10);
        private static volatile IsolatedStorageFile iso;
        private EventHandler streamready;
        private static volatile WebClient wc = new WebClient();
    
        // Events
        internal event EventHandler downloaderror
        {
            add
            {
                EventHandler handler2;
                EventHandler downloaderror = this.downloaderror;
                do
                {
                    handler2 = downloaderror;
                    EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value);
                    downloaderror = Interlocked.CompareExchange<EventHandler>(ref this.downloaderror, handler3, handler2);
                }
                while (downloaderror != handler2);
            }
            remove
            {
                EventHandler handler2;
                EventHandler downloaderror = this.downloaderror;
                do
                {
                    handler2 = downloaderror;
                    EventHandler handler3 = (EventHandler) Delegate.Remove(handler2, value);
                    downloaderror = Interlocked.CompareExchange<EventHandler>(ref this.downloaderror, handler3, handler2);
                }
                while (downloaderror != handler2);
            }
        }
    
        internal event EventHandler streamready
        {
            add
            {
                EventHandler handler2;
                EventHandler streamready = this.streamready;
                do
                {
                    handler2 = streamready;
                    EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value);
                    streamready = Interlocked.CompareExchange<EventHandler>(ref this.streamready, handler3, handler2);
                }
                while (streamready != handler2);
            }
            remove
            {
                EventHandler handler2;
                EventHandler streamready = this.streamready;
                do
                {
                    handler2 = streamready;
                    EventHandler handler3 = (EventHandler) Delegate.Remove(handler2, value);
                    streamready = Interlocked.CompareExchange<EventHandler>(ref this.streamready, handler3, handler2);
                }
                while (streamready != handler2);
            }
        }
    
        // Methods
        static CacheNetworkdFile()
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.set_Interval(new TimeSpan(0, 0, 1));
            _dispatchertimer = timer;
            iso = null;
            iso = IsolatedStorageFile.GetUserStoreForApplication();
            CacheExpire = new TimeSpan(3, 0, 0, 0);
            wc.add_OpenReadCompleted(new OpenReadCompletedEventHandler(null, (IntPtr) wc_OpenReadCompleted));
            _dispatchertimer.add_Tick(new EventHandler(CacheNetworkdFile._dispatchertimer_Tick));
            _dispatchertimer.Start();
        }
    
        private CacheNetworkdFile(Uri uri)
        {
            this._uri = uri;
        }
    
        private static void _dispatchertimer_Tick(object sender, EventArgs e)
        {
            NextDownload();
        }
    
        public static void AddBind(Uri uri, DependencyObject obj, DependencyProperty property)
        {
            propertybind propertybind2 = new propertybind {
                _uri = uri,
                _obj = obj,
                _property = property
            };
            propertybind item = propertybind2;
            if (!_bindlist.Contains(item))
            {
                _bindlist.Add(item);
            }
            downloadlist.Push(uri);
            CacheNetworkdFile cacheNetworkFile = GetCacheNetworkFile(uri);
            if (cacheNetworkFile.ExistCache)
            {
                cacheNetworkFile.OnStreamReady();
            }
        }
    
        private static void c_streamready(object sender, EventArgs e)
        {
            <>c__DisplayClass4 class2;
            CacheNetworkdFile file = (CacheNetworkdFile) sender;
            Uri u = file._uri;
            propertybind[] propertybindArray = Enumerable.ToArray<propertybind>(Enumerable.Where<propertybind>(_bindlist, new Func<propertybind, bool>(class2, (IntPtr) this.<c_streamready>b__3)));
            if ((propertybindArray != null) && (propertybindArray.Length != 0))
            {
                for (int i = 0; i < propertybindArray.Length; i++)
                {
                    DateTime time;
                    Stream stream = file.LoadStream(out time);
                    propertybindArray[i].bind(stream, time);
                }
            }
        }
    
        private static CacheNetworkdFile GetCacheNetworkFile(Uri uri)
        {
            if (uri == null)
            {
                throw new NullReferenceException("Uri can not be empty.");
            }
            if (!_cachelist.ContainsKey(uri))
            {
                CacheNetworkdFile file = new CacheNetworkdFile(uri);
                _cachelist.Add(uri, file);
                file.streamready += new EventHandler(CacheNetworkdFile.c_streamready);
                downloadlist.Push(uri);
                NextDownload();
            }
            return _cachelist[uri];
        }
    
        private DateTime GetLastWriteTime()
        {
            string str = SHA256(this._uri.ToString().ToLower());
            lock (iso)
            {
                if (iso.FileExists(@"CacheNetworkdFile\" + str))
                {
                    return iso.GetLastWriteTime(@"CacheNetworkdFile\" + str).DateTime;
                }
                return DateTime.MinValue;
            }
        }
    
        private Stream LoadStream(out DateTime filemodifydate)
        {
            string str = SHA256(this._uri.ToString().ToLower());
            lock (iso)
            {
                if (iso.FileExists(@"CacheNetworkdFile\" + str))
                {
                    IsolatedStorageFileStream stream = iso.OpenFile(@"CacheNetworkdFile\" + str, FileMode.Open);
                    MemoryStream stream2 = new MemoryStream();
                    byte[] buffer = new byte[0x4000];
                    while (true)
                    {
                        int count = stream.Read(buffer, 0, buffer.Length);
                        if (count == 0)
                        {
                            break;
                        }
                        stream2.Write(buffer, 0, count);
                    }
                    stream.Close();
                    stream.Dispose();
                    filemodifydate = iso.GetLastWriteTime(@"CacheNetworkdFile\" + str).DateTime;
                    return stream2;
                }
            }
            filemodifydate = DateTime.MinValue;
            return null;
        }
    
        private static void NextDownload()
        {
            if (!wc.get_IsBusy() && (downloadlist.Count > 0))
            {
                Uri uri = downloadlist.Pop();
                CacheNetworkdFile cacheNetworkFile = GetCacheNetworkFile(uri);
                if ((DateTime.Now - cacheNetworkFile.GetLastWriteTime()) > CacheExpire)
                {
                    wc.OpenReadAsync(uri, uri);
                }
                else
                {
                    NextDownload();
                }
            }
        }
    
        private void OnDownloadError()
        {
            if (this.downloaderror != null)
            {
                this.downloaderror(this, new EventArgs());
            }
        }
    
        private void OnStreamReady()
        {
            if (this.streamready != null)
            {
                this.streamready(this, new EventArgs());
            }
        }
    
        public static void RemoveBind(Uri uri, DependencyObject obj, DependencyProperty property)
        {
            propertybind propertybind2 = new propertybind {
                _uri = uri,
                _obj = obj,
                _property = property
            };
            propertybind item = propertybind2;
            if (_bindlist.Contains(item))
            {
                _bindlist.Remove(item);
            }
        }
    
        private void SaveStream(Stream sm)
        {
            string str = SHA256(this._uri.ToString().ToLower());
            lock (iso)
            {
                if (!iso.DirectoryExists("CacheNetworkdFile"))
                {
                    iso.CreateDirectory("CacheNetworkdFile");
                }
                IsolatedStorageFileStream stream = iso.OpenFile(@"CacheNetworkdFile\" + str, FileMode.Create, FileAccess.Write);
                byte[] buffer = new byte[0x4000];
                while (true)
                {
                    int count = sm.Read(buffer, 0, buffer.Length);
                    if (count == 0)
                    {
                        break;
                    }
                    stream.Write(buffer, 0, count);
                    stream.Flush();
                }
                stream.Close();
                stream.Dispose();
            }
        }
    
        private static string SHA256(string src)
        {
            if (string.IsNullOrEmpty(src))
            {
                return "";
            }
            return SHA256(Encoding.UTF8.GetBytes(src));
        }
    
        private static string SHA256(byte[] src)
        {
            if ((src == null) || (src.Length == 0))
            {
                return "";
            }
            byte[] buffer = new SHA256Managed().ComputeHash(src);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < buffer.Length; i++)
            {
                builder.Append(buffer[i].ToString("X2"));
            }
            return builder.ToString();
        }
    
        private static void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if ((e.UserState != null) && (e.UserState is Uri))
            {
                CacheNetworkdFile cacheNetworkFile = GetCacheNetworkFile((Uri) e.UserState);
                if ((e.Cancelled || (e.Error != null)) || (e.get_Result() == null))
                {
                    cacheNetworkFile.OnDownloadError();
                }
                else
                {
                    cacheNetworkFile.SaveStream(e.get_Result());
                    e.get_Result().Close();
                    e.get_Result().Dispose();
                    cacheNetworkFile.OnStreamReady();
                }
            }
            NextDownload();
        }
    
        // Properties
        public static TimeSpan CacheExpire
        {
            [CompilerGenerated]
            get
            {
                return <CacheExpire>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                <CacheExpire>k__BackingField = value;
            }
        }
    
        private bool ExistCache
        {
            get
            {
                string str = SHA256(this._uri.ToString().ToLower());
                lock (iso)
                {
                    if (iso.FileExists(@"CacheNetworkdFile\" + str))
                    {
                        if (NetworkInterface.GetIsNetworkAvailable())
                        {
                            DateTime dateTime = iso.GetLastWriteTime(@"CacheNetworkdFile\" + str).DateTime;
                            return ((DateTime.Now - dateTime) <= CacheExpire);
                        }
                        return true;
                    }
                    return false;
                }
            }
        }
    
        // Nested Types
        private class propertybind
        {
            // Fields
            public DependencyObject _obj;
            public DependencyProperty _property;
            public Uri _uri;
            private DateTime updatefilever = DateTime.MinValue;
    
            // Methods
            public void bind(object value, DateTime filemodifydate)
            {
                if ((((filemodifydate > DateTime.MinValue) && (this._uri != null)) && (this._property != null)) && (this._obj != null))
                {
                    this._obj.get_Dispatcher().BeginInvoke(new setvalue(this._obj.SetValue), new object[] { this._property, value });
                }
            }
    
            public override bool Equals(object obj)
            {
                if (obj == null)
                {
                    return false;
                }
                if (!(obj is CacheNetworkdFile.propertybind))
                {
                    return false;
                }
                CacheNetworkdFile.propertybind propertybind = (CacheNetworkdFile.propertybind) obj;
                if (this._uri != propertybind._uri)
                {
                    return false;
                }
                if (this._obj != propertybind._obj)
                {
                    return false;
                }
                if (this._property != propertybind._property)
                {
                    return false;
                }
                return true;
            }
    
            public override int GetHashCode()
            {
                int hashCode = 0;
                if (this._uri != null)
                {
                    hashCode = this._uri.GetHashCode();
                }
                if (this._obj != null)
                {
                    hashCode = (hashCode == 0) ? this._obj.GetHashCode() : (hashCode ^ this._obj.GetHashCode());
                }
                if (this._property != null)
                {
                    hashCode = (hashCode == 0) ? this._property.GetHashCode() : (hashCode ^ this._property.GetHashCode());
                }
                return hashCode;
            }
    
            public static bool operator ==(CacheNetworkdFile.propertybind a, CacheNetworkdFile.propertybind b)
            {
                return a.Equals(b);
            }
    
            public static bool operator !=(CacheNetworkdFile.propertybind a, CacheNetworkdFile.propertybind b)
            {
                return !a.Equals(b);
            }
    
            // Nested Types
            private delegate void setvalue(DependencyProperty p, object v);
        }
    }
    
     
    Collapse Methods
     

    在项目添加对这个Dll的应用

    在MainPage.xaml中添加

     xmlns:bw="clr-namespace:b_wind.WindowsPhone.Cache;assembly=CacheNetworkFile"

    在添加资源

     <phone:PhoneApplicationPage.Resources>
            <bw:CacheNetworkImageConvert x:Key="CacheImageConvert1" />
        </phone:PhoneApplicationPage.Resources>

    MainPage.xaml的设计界面

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <ListBox Height="481" HorizontalAlignment="Left" Margin="-4,120,0,0" Name="listBox1" VerticalAlignment="Top" Width="460">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Image  Height="106" Width="153"  Source="{Binding Converter={StaticResource CacheImageConvert1}}"></Image>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <Button Content="加载图片" Height="72" Name="button1" Width="160" Margin="308,-13,-12,548" Click="button1_Click" />
                <Button Content="清空列表" Height="72" HorizontalAlignment="Left" Margin="151,52,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="button2_Click" />
                <Button Content="清空缓存" Height="72" HorizontalAlignment="Left" Margin="151,-13,0,0" Name="button3" VerticalAlignment="Top" Width="160" Click="button3_Click" />
                <Button Content="添加项" Height="72" HorizontalAlignment="Left" Margin="308,52,0,0" Name="button4" VerticalAlignment="Top" Width="160" Click="button4_Click" />
            </Grid>

    MainPage.xaml.cs代码

    View Code
    public partial class MainPage : PhoneApplicationPage
        {
            ObservableCollection<string> l = new ObservableCollection<string>();
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                l.Clear();
                l.Add("http://bbs.51credit.com/static/image/common/pn_post.png");
                l.Add("http://ww4.sinaimg.cn/thumbnail/7cf05c2djw1drbb4m2rw2j.jpg");
                l.Add("http://ww1.sinaimg.cn/thumbnail/6c27f3a4jw1drbc2v6bmsj.jpg");
                l.Add("http://ww4.sinaimg.cn/thumbnail/6b6e567cjw1drb3plcg4sj.jpg");
                l.Add("http://ww3.sinaimg.cn/thumbnail/64d25c69jw1dr7smoyg41j.jpg");
    
                listBox1.ItemsSource = l;
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                l.Clear();
            }
    
            private void button3_Click(object sender, RoutedEventArgs e)
            {
                using (var iso = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
                {
                    iso.Remove();
                }
            }
    
            private void button4_Click(object sender, RoutedEventArgs e)
            {
                l.Add("http://ww3.sinaimg.cn/thumbnail/62037b5ajw1drd8g24zn9j.jpg");
            }
        }

    源代码下载地址:http://vdisk.weibo.com/s/aFuJX


     

  • 相关阅读:
    Javascript特效实现鼠标移动到小图,查看大图效果;
    Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
    Asp.Net技术的学习顺序
    Asp.net中用来代替Response.Write("<script>alert('错误信息');</script>");
    python测试例子
    基于socket 的web服务器检测
    python xml解析
    MySQLdb 简单说明
    python 实现简单的计算器
    XML SAX or DOM
  • 原文地址:https://www.cnblogs.com/fxiaoquan/p/2643144.html
Copyright © 2011-2022 走看看