X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=OpenTween%2FImageListViewItem.cs;h=43b6da68d829420e5b4b7006657c273383ff9f28;hb=69f6aa59a347591e11e03c99ac02e483b0ac686a;hp=e4380f91ee91ffbe109ffc1fd939d071b72d99d2;hpb=81f94a5a778e384d0cafe6e07a8d3878fe8ab7dd;p=opentween%2Fopen-tween.git diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index e4380f91..43b6da68 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -25,19 +25,29 @@ // Boston, MA 02110-1301, USA. using System; -using System.Drawing; -using System.Net; -using System.Windows.Forms; +using System.Net.Http; +using System.Runtime.Serialization; using System.Threading.Tasks; +using System.Windows.Forms; namespace OpenTween { + [Serializable] public class ImageListViewItem : ListViewItem { protected readonly ImageCache imageCache; protected readonly string imageUrl; + /// + /// 状態表示に使用するアイコンのインデックスを取得・設定する。 + /// + /// + /// StateImageIndex は不必要な処理が挟まるため、使用しないようにする。 + /// + public int StateIndex { get; set; } + private WeakReference imageReference = new WeakReference(null); + private Task imageTask = null; public event EventHandler ImageDownloaded; @@ -47,51 +57,60 @@ namespace OpenTween } public ImageListViewItem(string[] items, ImageCache imageCache, string imageUrl) - : base(items, imageUrl) + : base(items) { this.imageCache = imageCache; this.imageUrl = imageUrl; + this.StateIndex = -1; - if (imageCache != null) - { - var image = imageCache.TryGetFromCache(imageUrl); + var image = imageCache?.TryGetFromCache(imageUrl); + + if (image != null) + this.imageReference.Target = image; + } + + protected ImageListViewItem(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } - if (image == null) - this.GetImageAsync(); - else - this.imageReference.Target = image; + public Task GetImageAsync(bool force = false) + { + if (this.imageTask == null || this.imageTask.IsCompleted) + { + this.imageTask = this.GetImageAsyncInternal(force); } + + return this.imageTask; } - private Task GetImageAsync(bool force = false) + private async Task GetImageAsyncInternal(bool force) { if (string.IsNullOrEmpty(this.imageUrl)) - return Task.FromResult(0); + return; - var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); + if (!force && this.imageReference.Target != null) + return; - return this.imageCache.DownloadImageAsync(this.imageUrl, force) - .ContinueWith(t => - { - if (t.IsFaulted) - { - t.Exception.Flatten().Handle(x => x is WebException || x is InvalidImageException || x is TaskCanceledException); - return; - } + try + { + var image = await this.imageCache.DownloadImageAsync(this.imageUrl, force); - this.imageReference.Target = t.Result; + this.imageReference.Target = image; - if (this.ListView == null || !this.ListView.Created || this.ListView.IsDisposed) - return; + if (this.ListView == null || !this.ListView.Created || this.ListView.IsDisposed) + return; - if (this.Index < this.ListView.VirtualListSize) - { - this.ListView.RedrawItems(this.Index, this.Index, true); + if (this.Index < this.ListView.VirtualListSize) + { + this.ListView.RedrawItems(this.Index, this.Index, true); - if (this.ImageDownloaded != null) - this.ImageDownloaded(this, EventArgs.Empty); - } - }, uiScheduler); + this.ImageDownloaded?.Invoke(this, EventArgs.Empty); + } + } + catch (HttpRequestException) { } + catch (InvalidImageException) { } + catch (TaskCanceledException) { } } public MemoryImage Image @@ -102,10 +121,10 @@ namespace OpenTween } } - public void RefreshImage() + public Task RefreshImageAsync() { this.imageReference.Target = null; - this.GetImageAsync(true); + return this.GetImageAsync(true); } } }