예제 #1
0
        public void GetImageAsync(FacebookImageDimensions requestedSize, GetImageSourceAsyncCallback callback)
        {
            Verify.IsNotNull(callback, "callback");

            Assert.IsNotNull(SourceService);
            Assert.IsNotNull(SourceService.WebGetter);

            SmallUri ss = _GetSmallUriFromRequestedSize(requestedSize);

            if (ss == default(SmallUri))
            {
                callback(this, new GetImageSourceCompletedEventArgs(new InvalidOperationException("The requested image doesn't exist"), false, this));
            }

            BitmapSource img;

            if (_TryGetFromWeakCache(requestedSize, out img))
            {
                callback(this, new GetImageSourceCompletedEventArgs(img, this));
            }

            var userState = new _ImageCallbackState {
                Callback = callback, RequestedSize = requestedSize
            };

            SourceService.WebGetter.GetImageSourceAsync(this, userState, ss, _AddWeakCacheCallback);
        }
예제 #2
0
        public bool IsCached(FacebookImageDimensions requestedSize)
        {
            SmallUri sizedString = _GetSmallUriFromRequestedSize(requestedSize);
            //Assert.IsNotDefault(sizedString);
            string path;

            return(SourceService.WebGetter.TryGetImageFile(sizedString, out path));
        }
예제 #3
0
        private string _GetCacheLocation(SmallUri ssUri)
        {
            string path = _GenerateCachePath(ssUri);

            if (File.Exists(path))
            {
                return(path);
            }
            return(null);
        }
예제 #4
0
        private string _GenerateCachePath(SmallUri ssUri)
        {
            string key = ssUri.GetString();

            if (key.Length > 100)
            {
                key = "hash(" + Utility.GetHashString(key) + ")_" + key.Substring(key.Length - 80);
            }

            return(Path.Combine(_cachePath, Utility.MakeValidFileName(key)));
        }
예제 #5
0
        public void GetLocalImagePathAsync(object sender, object userState, SmallUri ssUri, SaveImageAsyncCallback callback)
        {
            //Verify.UriIsAbsolute(uri, "uri");
            Verify.IsNotNull(sender, "sender");
            // UserState may be null.
            // Verify.IsNotNull(userState, "userState");
            Verify.IsNotNull(callback, "callback");

            if (_disposed)
            {
                callback(this, new SaveImageCompletedEventArgs(new ObjectDisposedException("this"), false, userState));
                return;
            }

            if (default(SmallUri) == ssUri)
            {
                callback(this, new SaveImageCompletedEventArgs(new ArgumentException("The requested image doesn't exist.", "ssUri"), false, userState));
                return;
            }

            string cacheLocation = _GetCacheLocation(ssUri);

            if (cacheLocation != null)
            {
                callback(this, new SaveImageCompletedEventArgs(cacheLocation, userState));
                return;
            }

            // Make asynchronous request to download the image and get the local path.
            var imageRequest = new _DataRequest
            {
                Sender    = sender,
                UserState = userState,
                SmallUri  = ssUri,
                Callback  = callback,
            };

            bool needToQueue = false;

            lock (_webLock)
            {
                needToQueue = !_asyncWebRequestPool.HasPendingRequests;
                _activeWebRequests.Push(imageRequest);
            }

            if (needToQueue)
            {
                _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
                _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
            }
        }
예제 #6
0
        public void QueueImageRequest(SmallUri ssUri)
        {
            if (_disposed)
            {
                return;
            }

            if (ssUri == default(SmallUri))
            {
                return;
            }

            //Verify.UriIsAbsolute(uri, "uri");

            string path;

            if (TryGetImageFile(ssUri, out path))
            {
                return;
            }

            bool needToQueue = false;

            lock (_localLock)
            {
                needToQueue = !_asyncWebRequestPool.HasPendingRequests;
                _passiveWebRequests.Push(ssUri);
            }

            if (needToQueue)
            {
                // When we queue web requests, do it twice to effectively use the pool.
                // Since _ProcessNextWebRequest operates in a tight loop flushing our list it's not aware
                // that the work can be shared.
                _asyncWebRequestPool.QueueRequest(DispatcherPriority.Background, _ProcessNextWebRequest, null);
                _asyncWebRequestPool.QueueRequest(DispatcherPriority.Background, _ProcessNextWebRequest, null);
            }
        }
예제 #7
0
        private void _ProcessNextWebRequest(object unused)
        {
            if (_asyncWebRequestPool == null)
            {
                return;
            }

            var webClient = _asyncWebRequestPool.Tag as WebClient;

            Assert.IsNotNull(webClient);

            while (_asyncWebRequestPool != null)
            {
                // Retrieve the next data request for processing.
                _DataRequest activeRequest = null;
                SmallUri     ssUri         = default(SmallUri);
                bool         isPassive     = false;

                lock (_webLock)
                {
                    while (_activeWebRequests.Count > 0)
                    {
                        activeRequest = _activeWebRequests.Pop();
                        Assert.IsNotNull(activeRequest);
                        if (!activeRequest.Canceled)
                        {
                            ssUri = activeRequest.SmallUri;
                            break;
                        }
                    }

                    if (ssUri == default(SmallUri) && _passiveWebRequests.Count > 0)
                    {
                        ssUri     = _passiveWebRequests.Pop();
                        isPassive = true;
                    }

                    if (ssUri == default(SmallUri))
                    {
                        Assert.AreEqual(0, _activeWebRequests.Count);
                        Assert.AreEqual(0, _passiveWebRequests.Count);
                        return;
                    }
                }

                try
                {
                    string localCachePath = _GenerateCachePath(ssUri);
                    if (!File.Exists(localCachePath))
                    {
                        // There's a potential race here with other attempts to write the same file.
                        // We don't really care because there's not much we can do about it when
                        // it happens from multiple processes.
                        string tempFile = Path.GetTempFileName();
                        Uri    address  = ssUri.GetUri();
                        try
                        {
                            webClient.DownloadFile(address, tempFile);
                        }
                        catch (WebException)
                        {
                            // Fail once, just try again.  Servers are flakey.
                            // Fails again let it throw.  Caller is expected to catch.
                            webClient.DownloadFile(address, tempFile);
                        }

                        // Should really block multiple web requests for the same file, which causes this...
                        if (!Utility.TryFileMove(tempFile, localCachePath))
                        {
                            return;
                        }
                    }

                    if (!isPassive)
                    {
                        // If the _DataRequest has a SaveImageAsyncCallback then we're done.
                        var saveImageCallback = activeRequest.Callback as SaveImageAsyncCallback;
                        if (saveImageCallback != null)
                        {
                            saveImageCallback(this, new SaveImageCompletedEventArgs(localCachePath, activeRequest.UserState));
                            return;
                        }

                        bool needToQueue = false;
                        lock (_localLock)
                        {
                            if (_asyncPhotoPool != null)
                            {
                                needToQueue = !_asyncPhotoPool.HasPendingRequests;
                                _activePhotoRequests.Push(activeRequest);
                            }
                        }

                        if (needToQueue)
                        {
                            _asyncPhotoPool.QueueRequest(_ProcessNextLocalRequest, null);
                        }
                    }
                }
                catch
                { }
            }
        }
예제 #8
0
        private void _ProcessNextLocalRequest(object unused)
        {
            while (_asyncPhotoPool != null)
            {
                // Retrieve the next data request for processing.
                GetImageSourceAsyncCallback callback = null;
                object   userState = null;
                object   sender    = null;
                SmallUri ssUri     = default(SmallUri);

                lock (_localLock)
                {
                    while (_activePhotoRequests.Count > 0)
                    {
                        _DataRequest nextDataRequest = _activePhotoRequests.Pop();
                        Assert.IsTrue(nextDataRequest.Callback is GetImageSourceAsyncCallback);
                        if (!nextDataRequest.Canceled)
                        {
                            sender    = nextDataRequest.Sender;
                            callback  = (GetImageSourceAsyncCallback)nextDataRequest.Callback;
                            userState = nextDataRequest.UserState;
                            ssUri     = nextDataRequest.SmallUri;
                            break;
                        }
                    }

                    if (ssUri == default(SmallUri))
                    {
                        Assert.AreEqual(0, _activePhotoRequests.Count);
                        return;
                    }
                }

                Assert.IsNotNull(callback);
                GetImageSourceCompletedEventArgs callbackArgs = null;
                string localCachePath = null;
                try
                {
                    localCachePath = _GetCacheLocation(ssUri);
                    if (localCachePath == null)
                    {
                        callbackArgs = new GetImageSourceCompletedEventArgs(new FileNotFoundException(), false, userState);
                    }
                    else
                    {
                        using (Stream imageStream = File.Open(localCachePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            callbackArgs = new GetImageSourceCompletedEventArgs(_GetBitmapSourceFromStream(imageStream), userState);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!string.IsNullOrEmpty(localCachePath))
                    {
                        // If the cache is bad try removing the file so we can fetch it correctly next time.
                        try
                        {
                            File.Delete(localCachePath);
                        }
                        catch { }
                    }
                    callbackArgs = new GetImageSourceCompletedEventArgs(e, false, userState);
                }

                _callbackDispatcher.BeginInvoke(callback, sender, callbackArgs);
            }
        }
예제 #9
0
 public bool TryGetImageFile(SmallUri ssUri, out string path)
 {
     _Verify();
     path = _GetCacheLocation(ssUri);
     return(path != null);
 }
예제 #10
0
        public void GetImageSourceAsync(object sender, object userState, SmallUri ssUri, GetImageSourceAsyncCallback callback)
        {
            //Verify.UriIsAbsolute(uri, "uri");
            Verify.IsNotNull(sender, "sender");
            // UserState may be null.
            // Verify.IsNotNull(userState, "userState");
            Verify.IsNotNull(callback, "callback");

            if (_disposed)
            {
                callback(this, new GetImageSourceCompletedEventArgs(new ObjectDisposedException("this"), false, userState));
                return;
            }

            if (default(SmallUri) == ssUri)
            {
                callback(this, new GetImageSourceCompletedEventArgs(new ArgumentException("The requested image doesn't exist.", "ssUri"), false, userState));
                return;
            }

            // Make asynchronous request to get ImageSource object from the data feed.
            var imageRequest = new _DataRequest
            {
                Sender    = sender,
                UserState = userState,
                SmallUri  = ssUri,
                Callback  = callback,
            };

            bool needToCache = _GetCacheLocation(ssUri) == null;

            if (needToCache)
            {
                bool needToQueue = false;
                lock (_webLock)
                {
                    needToQueue = !_asyncWebRequestPool.HasPendingRequests;
                    _activeWebRequests.Push(imageRequest);
                }

                if (needToQueue)
                {
                    _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
                    _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
                }
            }
            else
            {
                bool needToQueue = false;
                lock (_localLock)
                {
                    needToQueue = !_asyncPhotoPool.HasPendingRequests;
                    _activePhotoRequests.Push(imageRequest);
                }

                if (needToQueue)
                {
                    _asyncPhotoPool.QueueRequest(_ProcessNextLocalRequest, null);
                }
            }
        }
 internal SaveFileCompletedEventArgs(string path, object userState, SmallUri uri)
     : base(null, false, userState)
 {
     Verify.IsNeitherNullNorEmpty(path, "path");
     Assert.IsTrue(File.Exists(path));
     FilePath = path;
     SmallUri = uri;
 }
 public PageCompletedEventArgs(string pageContent, object userState, SmallUri uri)
     : base(null, false, userState)
 {
     PageContent = pageContent;
     SmallUri = uri;
 }
        /// <summary>
        /// Download the web page specified in the ssUri
        /// </summary>
        /// <param name="sender">sender of the request</param>
        /// <param name="userState">user state - can be null</param>
        /// <param name="ssUri">uri to the page to download</param>
        /// <param name="callback">callback to call when download is complete</param>
        public void DownloadPageAsync(object sender, object userState, SmallUri ssUri, PageAsyncCallback callback)
        {
            if (_disposed)
            {
                callback(this, new PageCompletedEventArgs(new ObjectDisposedException("this"), false, userState));
                return;
            }

            if (default(SmallUri) == ssUri)
            {
                if (callback != null)
                    callback(this, new PageCompletedEventArgs(new ArgumentException("The requested page doesn't exist.", "ssUri"), false, userState));
                return;
            }

            // Make asynchronous request to download the image and get the local path.
            var pageRequest = new PageRequest
            {
                Sender = sender,
                UserState = userState,
                SmallUri = ssUri,
                Callback = callback
            };

            bool needToQueue = false;
            lock (_webLock)
            {
                needToQueue = !_asyncWebRequestPool.HasPendingRequests;
                _activeWebRequests.Enqueue(pageRequest);
            }

            if (needToQueue)
                _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
        }
        /// <summary>
        /// Download the specified file asynchroniously
        /// </summary>
        /// <param name="sender">sender of the request</param>
        /// <param name="userState">user state - can be null</param>
        /// <param name="ssUri">uri to the file to download</param>
        /// <param name="callback">callback to call when download is complete - can be null if you just want to download it in the background</param>
        /// <param name="pathToStore">directory where the file should be stored</param>
        /// <param name="fileName">filename of the file. If null then MD5 hash is computed from the uri and used as a filename - good to cache images</param>
        public void DownloadFileAsync(object sender, object userState, SmallUri ssUri, SaveFileAsyncCallback callback, string pathToStore, string fileName = null)
        {
            if (_disposed)
            {
                callback(this, new SaveFileCompletedEventArgs(new ObjectDisposedException("this"), false, userState));
                return;
            }

            if (default(SmallUri) == ssUri)
            {
                if (callback != null)
                    callback(this, new SaveFileCompletedEventArgs(new ArgumentException("The requested image doesn't exist.", "ssUri"), false, userState));
                return;
            }

            if (String.IsNullOrEmpty(fileName))
                fileName = ComputeUrlHash(ssUri.GetString());

            string destinationFullPath = Path.Combine(pathToStore, fileName);
            if (File.Exists(destinationFullPath))
            {
                callback(this, new SaveFileCompletedEventArgs(destinationFullPath, userState, ssUri));
                return;
            }

            // Make asynchronous request to download the image and get the local path.
            var fileRequest = new FileRequest
            {
                Sender = sender,
                UserState = userState,
                SmallUri = ssUri,
                Callback = callback,
                DestinationFileName = Path.Combine(pathToStore, fileName)
            };

            bool needToQueue = false;
            lock (_webLock)
            {
                needToQueue = !_asyncWebRequestPool.HasPendingRequests;
                if (callback != null)
                    _activeWebRequests.Enqueue(fileRequest);
                else
                    _passiveWebRequests.Enqueue(fileRequest);
            }

            if (needToQueue)
                _asyncWebRequestPool.QueueRequest(_ProcessNextWebRequest, null);
        }