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


 

你可能感兴趣的:(NetWork)