Example #1
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);
            }
        }
Example #2
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
                { }
            }
        }
Example #3
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);
            }
        }
Example #4
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);
                }
            }
        }