From 3b48fbde4d5496c0a6030faf7155f20a387a229c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 16:05:53 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.7.1-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 6 +++--- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 65a658fe5..26dc4680e 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.7.0.0")] +[assembly: AssemblyVersion("2.7.0.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 21be83480..3f30a561d 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,6 +571,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Unreleased + /// ///==== Ver 2.7.0(2022/07/30) /// * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 /// * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 @@ -580,9 +582,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 /// * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 /// * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 - /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不具合を修正 - /// - ///==== Ver 2 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 875763b8d..2cfcc5038 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Unreleased + ==== Ver 2.7.0(2022/07/30) * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 diff --git a/appveyor.yml b/appveyor.yml index 676677d00..f1a03ecfa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.6.0.{build} +version: 2.7.0.{build} os: Visual Studio 2022 From eef42e6e8e3e3be2884ada0277eee64c3a8d7bd1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 23:05:59 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E7=99=BA=E8=A8=80=E6=9C=AC=E6=96=87?= =?UTF-8?q?=E3=81=AE=E7=BF=BB=E8=A8=B3=E6=99=82=E3=81=AB=E7=99=BA=E7=94=9F?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E9=81=A9?= =?UTF-8?q?=E5=88=87=E3=81=AB=E5=87=A6=E7=90=86=E3=81=95=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Api/MicrosoftTranslatorApi.cs | 3 ++- OpenTween/Resources/ChangeLog.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index 363946841..6400a7ad7 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -128,7 +128,8 @@ public async Task UpdateAccessTokenIfExpired() using var response = await this.Http.SendAsync(request) .ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + if (!response.IsSuccessStatusCode) + throw new WebApiException(response.StatusCode.ToString()); var accessToken = await response.Content.ReadAsStringAsync() .ConfigureAwait(false); diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 2cfcc5038..8e0243309 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 ==== Ver 2.7.0(2022/07/30) * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 From 0b9006535e36e262513ff9b78ea27e2e658f9b6f Mon Sep 17 00:00:00 2001 From: kzrnm Date: Thu, 11 Aug 2022 00:58:35 +0900 Subject: [PATCH 3/6] =?UTF-8?q?.editorconfig=20=E3=81=AB=20csproj=20?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.editorconfig b/.editorconfig index 1c1266938..00bab1044 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,8 @@ +[*.csproj] +indent_style = space +indent_size = 2 +tab_width = 2 + [*.cs] indent_style = space tab_width = 4 From 8b11e0d94311308282cee7498e884fd1d2c56150 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 28 Aug 2022 13:59:37 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E6=8F=8F=E7=94=BB=E6=99=82=E3=81=AB=E3=83=87=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=83=AD=E3=83=83=E3=82=AF=E3=81=8C=E7=99=BA=E7=94=9F?= =?UTF-8?q?=E3=81=99=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(thx=20@Kazuki=5FAshiya!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STA thread 内での Mutex, WaitHandle によるロックはスレッドを完全に待機させる のではなく WM_PAINT などの一部のメッセージを処理しながら待機する動作になる。 これにより ImageCache.lockObject と HttpClient が内部で使用するロックとの間で デッドロックを生じさせていた。 参照: https://twitter.com/kim_upsilon/status/1561736832236150784 DrawItem イベントの処理中にはロックを使用しないのが最も望ましいが、暫定的な対処として ImageCache.lockObject のロック中に HttpClient.GetAsync を呼ばないように修正した。 Fixes: 92f0a891 ("ImageListViewItemを削除し通常のListViewItemのみを使用する") --- OpenTween/ImageCache.cs | 22 +++++++++------------- OpenTween/Resources/ChangeLog.txt | 1 + 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 690a7aced..76bfb639e 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -91,25 +91,21 @@ public Task DownloadImageAsync(string address, bool force = false) return Task.Run(() => { + Task? cachedImageTask; lock (this.lockObject) - { - this.InnerDictionary.TryGetValue(address, out var cachedImageTask); + this.InnerDictionary.TryGetValue(address, out cachedImageTask); - if (cachedImageTask != null) - { - if (force) - this.InnerDictionary.Remove(address); - else - return cachedImageTask; - } + if (cachedImageTask != null && !force) + return cachedImageTask; - cancelToken.ThrowIfCancellationRequested(); + cancelToken.ThrowIfCancellationRequested(); - var imageTask = this.FetchImageAsync(address, cancelToken); + var imageTask = this.FetchImageAsync(address, cancelToken); + + lock (this.lockObject) this.InnerDictionary[address] = imageTask; - return imageTask; - } + return imageTask; }, cancelToken); } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 8e0243309..26c6ec9f5 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 ==== Ver 2.7.0(2022/07/30) From 63b2b4eb8af900fda779ae2f367416b8797ecb72 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 28 Aug 2022 14:56:23 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E8=AA=AD=E3=81=BF=E8=BE=BC?= =?UTF-8?q?=E3=81=BF=E3=82=92=E6=98=8E=E7=A4=BA=E7=9A=84=E3=81=AB=E3=83=AF?= =?UTF-8?q?=E3=83=BC=E3=82=AB=E3=83=BC=E3=82=B9=E3=83=AC=E3=83=83=E3=83=89?= =?UTF-8?q?=E4=B8=8A=E3=81=A7=E8=A1=8C=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TweetThumbnail.ShowThumbnailAsync メソッドは従来から Task を使用した非同期 メソッドとなっているが、Task.Run を明示的に使用していないことから HttpClient.GetAsync はメインスレッド上で実行される状態となっていた。 HttpClient.GetAsync は内部で WaitHandle によるロックを使用しており、 STA thread 上で使用する場合に問題があることや、発言一覧の選択位置が変化した 場合などで DrawItem イベントとサムネイル画像の表示処理は並列に実行される ことが多く、ImageCache クラスの修正前はデッドロックを生じさせる原因の一つと なっていた。 そのため、修正後は HttpClient.GetAsync を含む処理を明示的に Task.Run で ワーカースレッド上で実行されるようにした。 --- OpenTween.Tests/OpenTween.Tests.csproj | 1 + OpenTween.Tests/TweetThumbnailTest.cs | 22 +++++++--------------- OpenTween/OTPictureBox.cs | 2 +- OpenTween/TweetThumbnail.cs | 4 ++-- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index a61fda3a5..3e6582c39 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -40,6 +40,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/OpenTween.Tests/TweetThumbnailTest.cs b/OpenTween.Tests/TweetThumbnailTest.cs index 9f274ec8b..04cd7e305 100644 --- a/OpenTween.Tests/TweetThumbnailTest.cs +++ b/OpenTween.Tests/TweetThumbnailTest.cs @@ -104,7 +104,7 @@ private void MyCommonSetup() MyCommon.EntryAssembly = mockAssembly.Object; } - [Fact] + [WinFormsFact] public void CreatePictureBoxTest() { using var thumbBox = new TweetThumbnail(); @@ -121,7 +121,7 @@ public void CreatePictureBoxTest() picbox.Dispose(); } - [Fact] + [WinFormsFact] public async Task CancelAsyncTest() { var post = new PostClass @@ -138,7 +138,6 @@ public async Task CancelAsyncTest() using var tokenSource = new CancellationTokenSource(); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token); tokenSource.Cancel(); @@ -147,7 +146,7 @@ public async Task CancelAsyncTest() Assert.True(task.IsCanceled); } - [Theory] + [WinFormsTheory] [InlineData(0)] [InlineData(1)] [InlineData(2)] @@ -178,7 +177,7 @@ public void SetThumbnailCountTest(int count) Assert.Equal(count - 1, thumbbox.scrollBar.Maximum); } - [Fact] + [WinFormsFact] public async Task ShowThumbnailAsyncTest() { var post = new PostClass @@ -193,7 +192,6 @@ public async Task ShowThumbnailAsyncTest() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(0, thumbbox.scrollBar.Maximum); @@ -211,7 +209,7 @@ public async Task ShowThumbnailAsyncTest() Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); } - [Fact] + [WinFormsFact] public async Task ShowThumbnailAsyncTest2() { var post = new PostClass @@ -227,7 +225,6 @@ public async Task ShowThumbnailAsyncTest2() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(1, thumbbox.scrollBar.Maximum); @@ -253,14 +250,12 @@ public async Task ShowThumbnailAsyncTest2() Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[1])); } - [Fact] + [WinFormsFact] public async Task ThumbnailLoadingEventTest() { using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post = new PostClass { TextFromApi = "てすと", @@ -274,8 +269,6 @@ await TestUtils.NotRaisesAsync( () => thumbbox.ShowThumbnailAsync(post) ); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post2 = new PostClass { TextFromApi = "てすと http://foo.example.com/abcd", @@ -292,7 +285,7 @@ await Assert.RaisesAsync( ); } - [Fact] + [WinFormsFact] public async Task ScrollTest() { var post = new PostClass @@ -308,7 +301,6 @@ public async Task ScrollTest() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(0, thumbbox.scrollBar.Minimum); diff --git a/OpenTween/OTPictureBox.cs b/OpenTween/OTPictureBox.cs index 5ebb65140..21a775323 100644 --- a/OpenTween/OTPictureBox.cs +++ b/OpenTween/OTPictureBox.cs @@ -112,7 +112,7 @@ public async Task SetImageFromTask(Func> imageTask, bool useSt if (useStatusImage) this.ShowInitialImage(); - var image = await imageTask(); + var image = await Task.Run(imageTask); if (id == this.currentImageTaskId) this.Image = image; diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index dddb955cb..c3b839918 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -131,8 +131,8 @@ private string GetImageSearchUriGoogle(string image_uri) private string GetImageSearchUriSauceNao(string imageUri) => @"https://saucenao.com/search.php?url=" + Uri.EscapeDataString(imageUri); - protected virtual Task> GetThumbailInfoAsync(PostClass post, CancellationToken token) - => this.ThumbGenerator.GetThumbnailsAsync(post, token); + protected async virtual Task> GetThumbailInfoAsync(PostClass post, CancellationToken token) + => await Task.Run(() => this.ThumbGenerator.GetThumbnailsAsync(post, token)); /// /// 表示するサムネイルの数を設定する From 341e11e63b0ebe94c1619de82de1c9915ab551f1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 3 Sep 2022 01:22:05 +0900 Subject: [PATCH 6/6] =?UTF-8?q?OpenTween=20v2.7.1=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 8 ++++---- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 26dc4680e..10392a6e2 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.7.0.1")] +[assembly: AssemblyVersion("2.7.1.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 3f30a561d..baa0084e9 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,7 +571,9 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Unreleased + ///==== Ver 2.7.1(2022/09/03) + /// * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) + /// * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 /// ///==== Ver 2.7.0(2022/07/30) /// * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 @@ -580,9 +582,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// - Twitter の API キーを独自に書き換えている場合で、Project への移行を完了できていない等の理由で API v2 を使用できない時はチェックを外してください /// * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 - /// * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 - /// * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 - /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 26c6ec9f5..533eb13a4 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Unreleased +==== Ver 2.7.1(2022/09/03) * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正