using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows.Forms;
using Xunit;
using Xunit.Extensions;
}
}
+ [Fact]
+ public async Task SetImageFromAsync_Test()
+ {
+ using (var picbox = new OTPictureBox())
+ {
+ // Mono でのテスト実行時にデッドロックする問題の対策
+ SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+
+ var tcs = new TaskCompletionSource<MemoryImage>();
+
+ var setImageTask = picbox.SetImageFromTask(() => tcs.Task);
+
+ Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image);
+
+ var image = this.CreateDummyImage();
+ tcs.SetResult(image);
+ await setImageTask;
+
+ Assert.Equal(image, picbox.Image);
+ }
+ }
+
+ [Fact]
+ public async Task SetImageFromAsync_ErrorTest()
+ {
+ using (var picbox = new OTPictureBox())
+ {
+ // Mono でのテスト実行時にデッドロックする問題の対策
+ SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+
+ var tcs = new TaskCompletionSource<MemoryImage>();
+
+ var setImageTask = picbox.SetImageFromTask(() => tcs.Task);
+
+ Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image);
+
+ tcs.SetException(new InvalidImageException());
+ await setImageTask;
+
+ Assert.Equal(picbox.ErrorImage, ((PictureBox)picbox).Image);
+ }
+ }
+
MemoryImage CreateDummyImage()
{
using (var bitmap = new Bitmap(100, 100))
using System.Threading.Tasks;
using System.Threading;
using System.Net;
+using System.Net.Http;
using System.IO;
namespace OpenTween
base.SizeMode = this.currentSizeMode;
}
+ public async Task SetImageFromTask(Func<Task<MemoryImage>> imageTask)
+ {
+ try
+ {
+ this.ShowInitialImage();
+ this.Image = await imageTask();
+ }
+ catch (Exception)
+ {
+ this.ShowErrorImage();
+ try
+ {
+ throw;
+ }
+ catch (HttpRequestException) { }
+ catch (InvalidImageException) { }
+ catch (TaskCanceledException) { }
+ catch (WebException) { }
+ }
+ }
+
protected override void OnPaint(PaintEventArgs pe)
{
try
{
if (this._curPost == null) return;
- var imageUrl = this._curPost.ImageUrl;
- try
+ await this.UserPicture.SetImageFromTask(async () =>
{
- var image = await this.IconCache.DownloadImageAsync(imageUrl, force: true);
+ var imageUrl = this._curPost.ImageUrl;
- this.ClearUserPicture();
- this.UserPicture.Image = image.Clone();
- }
- catch (Exception)
- {
- this.UserPicture.ShowErrorImage();
- try
- {
- throw;
- }
- catch (HttpRequestException) { }
- catch (InvalidImageException) { }
- catch (TaskCanceledException) { }
- }
+ var image = await this.IconCache.DownloadImageAsync(imageUrl, force: true)
+ .ConfigureAwait(false);
+
+ return await image.CloneAsync()
+ .ConfigureAwait(false);
+ });
}
private void SaveOriginalSizeIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
<data name="ApiUsageInfoMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>301, 24</value>
</data>
+ <data name="UserPicture.InitialImage" type="System.Resources.ResXNullRef, System.Windows.Forms">
+ <value />
+ </data>
<data name="UserPicture.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 4</value>
</data>
picbox.Tag = thumb;
picbox.ContextMenu = CreateContextMenu(thumb);
- var loadTask = this.SetThumbnailImageAsync(picbox, thumb, cancelToken);
+ var loadTask = picbox.SetImageFromTask(() => thumb.LoadThumbnailImageAsync(cancelToken));
loadTasks.Add(loadTask);
var tooltipText = thumb.TooltipText;
await Task.WhenAll(loadTasks).ConfigureAwait(false);
}
- private async Task SetThumbnailImageAsync(OTPictureBox picbox, ThumbnailInfo thumbInfo,
- CancellationToken cancelToken)
- {
- try
- {
- picbox.ShowInitialImage();
- picbox.Image = await thumbInfo.LoadThumbnailImageAsync(cancelToken);
- }
- catch (Exception)
- {
- picbox.ShowErrorImage();
- try
- {
- throw;
- }
- catch (HttpRequestException) { }
- catch (InvalidImageException) { }
- catch (TaskCanceledException) { }
- }
- }
-
private ContextMenu CreateContextMenu(ThumbnailInfo thumb)
{
var contextMenu = new ContextMenu();
if (imageUri == null)
return;
- using (var http = MyCommon.CreateHttpClient())
+ await this.UserPicture.SetImageFromTask(async () =>
{
- var imageStream = await http.GetStreamAsync(imageUri.Replace("_normal", "_bigger"));
- this.UserPicture.Image = await MemoryImage.CopyFromStreamAsync(imageStream);
- }
+ using (var http = MyCommon.CreateHttpClient())
+ {
+ var imageStream = await http.GetStreamAsync(imageUri.Replace("_normal", "_bigger"))
+ .ConfigureAwait(false);
+
+ return await MemoryImage.CopyFromStreamAsync(imageStream)
+ .ConfigureAwait(false);
+ }
+ });
}
private async Task SetLinkLabelWebAsync(string uri)
<data name="UserPicture.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
+ <data name="UserPicture.InitialImage" type="System.Resources.ResXNullRef, System.Windows.Forms">
+ <value />
+ </data>
<data name="UserPicture.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 59</value>
</data>