public void Load(SafeUri uri) { if (is_disposed) { return; } //First, send a thumbnail if we have one if ((thumb = App.Instance.Container.Resolve <IThumbnailService> ().TryLoadThumbnail(uri, ThumbnailSize.Large)) != null) { pixbuf_orientation = ImageOrientation.TopLeft; AreaPrepared?.Invoke(this, new AreaPreparedEventArgs(true)); AreaUpdated?.Invoke(this, new AreaUpdatedEventArgs(new Rectangle(0, 0, thumb.Width, thumb.Height))); } using (var image_file = App.Instance.Container.Resolve <IImageFileFactory> ().Create(uri)) { image_stream = image_file.PixbufStream(); pixbuf_orientation = image_file.Orientation; } Loading = true; // The ThreadPool.QueueUserWorkItem hack is there cause, as the bytes to read are present in the stream, // the Read is CompletedAsynchronously, blocking the mainloop image_stream.BeginRead(buffer, 0, count, delegate(IAsyncResult r) { ThreadPool.QueueUserWorkItem(delegate { HandleReadDone(r); }); }, null); }
void HandleReadDone(IAsyncResult ar) { if (is_disposed) { return; } int byte_read = image_stream.EndRead(ar); lock (sync_handle) { if (byte_read == 0) { image_stream.Close(); Close(); Loading = false; notify_completed = true; } else { try { if (!is_disposed && Write(buffer, (ulong)byte_read)) { image_stream.BeginRead(buffer, 0, count, HandleReadDone, null); } } catch (ObjectDisposedException) { } catch (GLib.GException) { } } } GLib.Idle.Add(delegate { //Send the AreaPrepared event if (notify_prepared) { notify_prepared = false; if (thumb != null) { thumb.Dispose(); thumb = null; } AreaPrepared?.Invoke(this, new AreaPreparedEventArgs(false)); } //Send the AreaUpdated events if (damage != Rectangle.Zero) { AreaUpdated?.Invoke(this, new AreaUpdatedEventArgs(damage)); damage = Rectangle.Zero; } //Send the Completed event if (notify_completed) { notify_completed = false; OnCompleted(); } return(false); }); }