OSDN Git Service

シンプルな型名を使用する (IDE0049)
[opentween/open-tween.git] / OpenTween / Tween.cs
index d6b4107..1032221 100644 (file)
@@ -113,15 +113,15 @@ namespace OpenTween
         private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する
 
         //twitter解析部
-        private TwitterApi twitterApi = new TwitterApi();
+        private readonly TwitterApi twitterApi = new TwitterApi();
         private Twitter tw;
 
         //Growl呼び出し部
-        private GrowlHelper gh = new GrowlHelper(ApplicationSettings.ApplicationName);
+        private readonly GrowlHelper gh = new GrowlHelper(ApplicationSettings.ApplicationName);
 
         //サブ画面インスタンス
         internal SearchWordDialog SearchDialog = new SearchWordDialog();     //検索画面インスタンス
-        private OpenURL UrlDialog = new OpenURL();
+        private readonly OpenURL UrlDialog = new OpenURL();
         public AtIdSupplement AtIdSupl;     //@id補助
         public AtIdSupplement HashSupl;    //Hashtag補助
         public HashtagManage HashMgr;
@@ -135,7 +135,7 @@ namespace OpenTween
         private Color _clFav;               //Fav用文字色
         private Color _clOWL;               //片思い用文字色
         private Color _clRetweet;               //Retweet用文字色
-        private Color _clHighLight = Color.FromKnownColor(KnownColor.HighlightText);         //選択中の行用文字色
+        private readonly Color _clHighLight = Color.FromKnownColor(KnownColor.HighlightText);         //選択中の行用文字色
         private Font _fntDetail;            //発言詳細部用フォント
         private Color _clDetail;              //発言詳細部用色
         private Color _clDetailLink;          //発言詳細部用リンク文字色
@@ -160,23 +160,23 @@ namespace OpenTween
         private Icon ReplyIcon;               //5g
         private Icon ReplyIconBlink;          //6g
 
-        private ImageList _listViewImageList = new ImageList();    //ListViewItemの高さ変更用
+        private readonly ImageList _listViewImageList = new ImageList();    //ListViewItemの高さ変更用
 
         private PostClass _anchorPost;
         private bool _anchorFlag;        //true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
 
-        private List<StatusTextHistory> _history = new List<StatusTextHistory>();   //発言履歴
+        private readonly List<StatusTextHistory> _history = new List<StatusTextHistory>();   //発言履歴
         private int _hisIdx;                  //発言履歴カレントインデックス
 
         //発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
         private (long StatusId, string ScreenName)? inReplyTo = null; // リプライ先のステータスID・スクリーン名
 
         //時速表示用
-        private List<DateTimeUtc> _postTimestamps = new List<DateTimeUtc>();
-        private List<DateTimeUtc> _favTimestamps = new List<DateTimeUtc>();
+        private readonly List<DateTimeUtc> _postTimestamps = new List<DateTimeUtc>();
+        private readonly List<DateTimeUtc> _favTimestamps = new List<DateTimeUtc>();
 
         // 以下DrawItem関連
-        private SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
+        private readonly SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
         private SolidBrush _brsBackColorMine;
         private SolidBrush _brsBackColorAt;
         private SolidBrush _brsBackColorYou;
@@ -184,8 +184,8 @@ namespace OpenTween
         private SolidBrush _brsBackColorAtFromTarget;
         private SolidBrush _brsBackColorAtTo;
         private SolidBrush _brsBackColorNone;
-        private SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); //Listにフォーカスないときの選択行の背景色
-        private StringFormat sfTab = new StringFormat();
+        private readonly SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); //Listにフォーカスないときの選択行の背景色
+        private readonly StringFormat sfTab = new StringFormat();
 
         //////////////////////////////////////////////////////////////////////////////////////////////////////////
         private TabInformations _statuses;
@@ -211,11 +211,8 @@ namespace OpenTween
             /// <summary>キャッシュする範囲の終了インデックス</summary>
             public int EndIndex { get; set; }
 
-            /// <summary>キャッシュされた <see cref="ListViewItem"/> インスタンス</summary>
-            public ListViewItem[] ListItem { get; set; }
-
-            /// <summary>キャッシュされた範囲に対応する <see cref="PostClass"/> インスタンス</summary>
-            public PostClass[] Post { get; set; }
+            /// <summary>キャッシュされた範囲に対応する <see cref="ListViewItem"/> と <see cref="PostClass"/> の組</summary>
+            public (ListViewItem, PostClass)[] Cache { get; set; }
 
             /// <summary>キャッシュされたアイテムの件数</summary>
             public int Count
@@ -237,8 +234,7 @@ namespace OpenTween
             {
                 if (this.Contains(index))
                 {
-                    item = this.ListItem[index - this.StartIndex];
-                    post = this.Post[index - this.StartIndex];
+                    (item, post) = this.Cache[index - this.StartIndex];
                     return true;
                 }
                 else
@@ -253,24 +249,25 @@ namespace OpenTween
         private bool _isColumnChanged = false;
 
         private const int MAX_WORKER_THREADS = 20;
-        private SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS);
-        private CancellationTokenSource workerCts = new CancellationTokenSource();
-        private IProgress<string> workerProgress;
+        private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS);
+        private readonly CancellationTokenSource workerCts = new CancellationTokenSource();
+        private readonly IProgress<string> workerProgress;
 
         private int UnreadCounter = -1;
         private int UnreadAtCounter = -1;
 
-        private string[] ColumnOrgText = new string[9];
-        private string[] ColumnText = new string[9];
+        private readonly string[] ColumnOrgText = new string[9];
+        private readonly string[] ColumnText = new string[9];
 
         private bool _DoFavRetweetFlags = false;
-        private bool osResumed = false;
 
         //////////////////////////////////////////////////////////////////////////////////////////////////////////
-        private bool _colorize = false;
 
-        private System.Timers.Timer TimerTimeline = new System.Timers.Timer();
+        private readonly TimelineScheduler timelineScheduler = new TimelineScheduler();
         private ThrottlingTimer RefreshThrottlingTimer;
+        private ThrottlingTimer colorizeDebouncer;
+        private ThrottlingTimer selectionDebouncer;
+        private ThrottlingTimer saveConfigDebouncer;
 
         private string recommendedStatusFooter;
         private bool urlMultibyteSplit = false;
@@ -300,7 +297,7 @@ namespace OpenTween
         }
 
         private Stack<ReplyChain> replyChains; //[, ]でのリプライ移動の履歴
-        private Stack<(TabModel, PostClass)> selectPostChains = new Stack<(TabModel, PostClass)>(); //ポスト選択履歴
+        private readonly Stack<(TabModel, PostClass)> selectPostChains = new Stack<(TabModel, PostClass)>(); //ポスト選択履歴
 
         public TabModel CurrentTab
             => this._statuses.SelectedTab;
@@ -632,7 +629,7 @@ namespace OpenTween
             ColumnOrgText[6] = "";
             ColumnOrgText[7] = "Source";
 
-            int c = 0;
+            var c = 0;
             switch (_statuses.SortMode)
             {
                 case ComparerMode.Nickname:  //ニックネーム
@@ -789,8 +786,8 @@ namespace OpenTween
 
             Networking.Initialize();
 
-            bool saveRequired = false;
-            bool firstRun = false;
+            var saveRequired = false;
+            var firstRun = false;
 
             //ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
             if (string.IsNullOrEmpty(tw.Username))
@@ -819,7 +816,7 @@ namespace OpenTween
             tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck;
             tw.ReadOwnPost = SettingManager.Common.ReadOwnPost;
             tw.TrackWord = SettingManager.Common.TrackWord;
-            TrackToolStripMenuItem.Checked = !String.IsNullOrEmpty(tw.TrackWord);
+            TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(tw.TrackWord);
             tw.AllAtReply = SettingManager.Common.AllAtReply;
             AllrepliesToolStripMenuItem.Checked = tw.AllAtReply;
             ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve;
@@ -937,11 +934,11 @@ namespace OpenTween
             //タイトルバー領域
             if (this.WindowState != FormWindowState.Minimized)
             {
-                Rectangle tbarRect = new Rectangle(this._myLoc, new Size(_mySize.Width, SystemInformation.CaptionHeight));
-                bool outOfScreen = true;
+                var tbarRect = new Rectangle(this._myLoc, new Size(_mySize.Width, SystemInformation.CaptionHeight));
+                var outOfScreen = true;
                 if (Screen.AllScreens.Length == 1)    //ハングするとの報告
                 {
-                    foreach (Screen scr in Screen.AllScreens)
+                    foreach (var scr in Screen.AllScreens)
                     {
                         if (!Rectangle.Intersect(tbarRect, scr.Bounds).IsEmpty)
                         {
@@ -1085,7 +1082,7 @@ namespace OpenTween
             if (SettingManager.Common.HotkeyEnabled)
             {
                 //////グローバルホットキーの登録
-                HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
+                var modKey = HookGlobalHotkey.ModKeys.None;
                 if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt)
                     modKey |= HookGlobalHotkey.ModKeys.Alt;
                 if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control)
@@ -1113,17 +1110,31 @@ namespace OpenTween
 
             //タイマー設定
 
+            this.timelineScheduler.UpdateHome = () => this.InvokeAsync(() => this.RefreshTabAsync<HomeTabModel>());
+            this.timelineScheduler.UpdateMention = () => this.InvokeAsync(() => this.RefreshTabAsync<MentionsTabModel>());
+            this.timelineScheduler.UpdateDm = () => this.InvokeAsync(() => this.RefreshTabAsync<DirectMessagesTabModel>());
+            this.timelineScheduler.UpdatePublicSearch = () => this.InvokeAsync(() => this.RefreshTabAsync<PublicSearchTabModel>());
+            this.timelineScheduler.UpdateUser = () => this.InvokeAsync(() => this.RefreshTabAsync<UserTimelineTabModel>());
+            this.timelineScheduler.UpdateList = () => this.InvokeAsync(() => this.RefreshTabAsync<ListTimelineTabModel>());
+            this.timelineScheduler.UpdateConfig = () => this.InvokeAsync(() => Task.WhenAll(new[]
+            {
+                this.doGetFollowersMenu(),
+                this.RefreshBlockIdsAsync(),
+                this.RefreshMuteUserIdsAsync(),
+                this.RefreshNoRetweetIdsAsync(),
+                this.RefreshTwitterConfigurationAsync(),
+            }));
+            this.RefreshTimelineScheduler();
+
             var streamingRefreshInterval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod);
             this.RefreshThrottlingTimer = ThrottlingTimer.Throttle(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval);
+            this.colorizeDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.ColorizeList()), TimeSpan.FromMilliseconds(100), leading: true);
+            this.selectionDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100), leading: true);
+            this.saveConfigDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.SaveConfigsAll(ifModified: true)), TimeSpan.FromSeconds(1));
 
-            TimerTimeline.AutoReset = true;
-            TimerTimeline.SynchronizingObject = this;
-            //Recent取得間隔
-            TimerTimeline.Interval = 1000;
-            TimerTimeline.Enabled = true;
             //更新中アイコンアニメーション間隔
             TimerRefreshIcon.Interval = 200;
-            TimerRefreshIcon.Enabled = true;
+            TimerRefreshIcon.Enabled = false;
 
             _ignoreConfigSave = false;
             this.TweenMain_Resize(null, null);
@@ -1276,8 +1287,6 @@ namespace OpenTween
 
         private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) //Handles SettingDialog.IntervalChanged
         {
-            if (!TimerTimeline.Enabled) return;
-
             if (e.UserStream)
             {
                 var interval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod);
@@ -1286,107 +1295,48 @@ namespace OpenTween
                 oldTimer.Dispose();
             }
 
-            ResetTimers = e;
+            this.RefreshTimelineScheduler();
         }
 
-        private IntervalChangedEventArgs ResetTimers = IntervalChangedEventArgs.ResetAll;
+        private void RefreshTimelineScheduler()
+        {
+            this.timelineScheduler.UpdateIntervalHome = TimeSpan.FromSeconds(SettingManager.Common.TimelinePeriod);
+            this.timelineScheduler.UpdateIntervalMention = TimeSpan.FromSeconds(SettingManager.Common.ReplyPeriod);
+            this.timelineScheduler.UpdateIntervalDm = TimeSpan.FromSeconds(SettingManager.Common.DMPeriod);
+            this.timelineScheduler.UpdateIntervalPublicSearch = TimeSpan.FromSeconds(SettingManager.Common.PubSearchPeriod);
+            this.timelineScheduler.UpdateIntervalUser = TimeSpan.FromSeconds(SettingManager.Common.UserTimelinePeriod);
+            this.timelineScheduler.UpdateIntervalList = TimeSpan.FromSeconds(SettingManager.Common.ListsPeriod);
+            this.timelineScheduler.UpdateIntervalConfig = TimeSpan.FromHours(6);
+            this.timelineScheduler.UpdateAfterSystemResume = TimeSpan.FromSeconds(30);
 
-        private static int homeCounter = 0;
-        private static int mentionCounter = 0;
-        private static int dmCounter = 0;
-        private static int pubSearchCounter = 0;
-        private static int userTimelineCounter = 0;
-        private static int listsCounter = 0;
-        private static int ResumeWait = 0;
-        private static int refreshFollowers = 0;
+            this.timelineScheduler.RefreshSchedule();
+        }
 
-        private async void TimerTimeline_Elapsed(object sender, EventArgs e)
+        private void MarkSettingCommonModified()
         {
-            if (homeCounter > 0) Interlocked.Decrement(ref homeCounter);
-            if (mentionCounter > 0) Interlocked.Decrement(ref mentionCounter);
-            if (dmCounter > 0) Interlocked.Decrement(ref dmCounter);
-            if (pubSearchCounter > 0) Interlocked.Decrement(ref pubSearchCounter);
-            if (userTimelineCounter > 0) Interlocked.Decrement(ref userTimelineCounter);
-            if (listsCounter > 0) Interlocked.Decrement(ref listsCounter);
-            Interlocked.Increment(ref refreshFollowers);
+            if (this.saveConfigDebouncer == null)
+                return;
 
-            var refreshTasks = new List<Task>();
+            this.ModifySettingCommon = true;
+            this.saveConfigDebouncer.Call();
+        }
 
-            ////タイマー初期化
-            if (ResetTimers.Timeline || homeCounter <= 0 && SettingManager.Common.TimelinePeriod > 0)
-            {
-                Interlocked.Exchange(ref homeCounter, SettingManager.Common.TimelinePeriod);
-                if (!tw.IsUserstreamDataReceived && !ResetTimers.Timeline)
-                    refreshTasks.Add(this.RefreshTabAsync<HomeTabModel>());
-                ResetTimers.Timeline = false;
-            }
-            if (ResetTimers.Reply || mentionCounter <= 0 && SettingManager.Common.ReplyPeriod > 0)
-            {
-                Interlocked.Exchange(ref mentionCounter, SettingManager.Common.ReplyPeriod);
-                if (!tw.IsUserstreamDataReceived && !ResetTimers.Reply)
-                    refreshTasks.Add(this.RefreshTabAsync<MentionsTabModel>());
-                ResetTimers.Reply = false;
-            }
-            if (ResetTimers.DirectMessage || dmCounter <= 0 && SettingManager.Common.DMPeriod > 0)
-            {
-                Interlocked.Exchange(ref dmCounter, SettingManager.Common.DMPeriod);
-                if (!tw.IsUserstreamDataReceived && !ResetTimers.DirectMessage)
-                    refreshTasks.Add(this.RefreshTabAsync<DirectMessagesTabModel>());
-                ResetTimers.DirectMessage = false;
-            }
-            if (ResetTimers.PublicSearch || pubSearchCounter <= 0 && SettingManager.Common.PubSearchPeriod > 0)
-            {
-                Interlocked.Exchange(ref pubSearchCounter, SettingManager.Common.PubSearchPeriod);
-                if (!ResetTimers.PublicSearch)
-                    refreshTasks.Add(this.RefreshTabAsync<PublicSearchTabModel>());
-                ResetTimers.PublicSearch = false;
-            }
-            if (ResetTimers.UserTimeline || userTimelineCounter <= 0 && SettingManager.Common.UserTimelinePeriod > 0)
-            {
-                Interlocked.Exchange(ref userTimelineCounter, SettingManager.Common.UserTimelinePeriod);
-                if (!ResetTimers.UserTimeline)
-                    refreshTasks.Add(this.RefreshTabAsync<UserTimelineTabModel>());
-                ResetTimers.UserTimeline = false;
-            }
-            if (ResetTimers.Lists || listsCounter <= 0 && SettingManager.Common.ListsPeriod > 0)
-            {
-                Interlocked.Exchange(ref listsCounter, SettingManager.Common.ListsPeriod);
-                if (!ResetTimers.Lists)
-                    refreshTasks.Add(this.RefreshTabAsync<ListTimelineTabModel>());
-                ResetTimers.Lists = false;
-            }
-            if (refreshFollowers > 6 * 3600)
-            {
-                Interlocked.Exchange(ref refreshFollowers, 0);
-                refreshTasks.AddRange(new[]
-                {
-                    this.doGetFollowersMenu(),
-                    this.RefreshNoRetweetIdsAsync(),
-                    this.RefreshTwitterConfigurationAsync(),
-                });
-            }
-            if (osResumed)
-            {
-                Interlocked.Increment(ref ResumeWait);
-                if (ResumeWait > 30)
-                {
-                    osResumed = false;
-                    Interlocked.Exchange(ref ResumeWait, 0);
-                    refreshTasks.AddRange(new[]
-                    {
-                        this.RefreshTabAsync<HomeTabModel>(),
-                        this.RefreshTabAsync<MentionsTabModel>(),
-                        this.RefreshTabAsync<DirectMessagesTabModel>(),
-                        this.RefreshTabAsync<PublicSearchTabModel>(),
-                        this.RefreshTabAsync<UserTimelineTabModel>(),
-                        this.RefreshTabAsync<ListTimelineTabModel>(),
-                        this.doGetFollowersMenu(),
-                        this.RefreshTwitterConfigurationAsync(),
-                    });
-                }
-            }
+        private void MarkSettingLocalModified()
+        {
+            if (this.saveConfigDebouncer == null)
+                return;
 
-            await Task.WhenAll(refreshTasks);
+            this.ModifySettingLocal = true;
+            this.saveConfigDebouncer.Call();
+        }
+
+        internal void MarkSettingAtIdModified()
+        {
+            if (this.saveConfigDebouncer == null)
+                return;
+
+            this.ModifySettingAtId = true;
+            this.saveConfigDebouncer.Call();
         }
 
         private void RefreshTimeline()
@@ -1738,11 +1688,11 @@ namespace OpenTween
                     //Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる
                     if (SettingManager.Common.IsUseNotifyGrowl)
                     {
-                        StringBuilder sb = new StringBuilder();
-                        bool reply = false;
-                        bool dm = false;
+                        var sb = new StringBuilder();
+                        var reply = false;
+                        var dm = false;
 
-                        foreach (PostClass post in notifyPosts)
+                        foreach (var post in notifyPosts)
                         {
                             if (!(notifyPosts.Length > 3))
                             {
@@ -1768,7 +1718,7 @@ namespace OpenTween
                                 if (notifyPosts.Last() != post) continue;
                             }
 
-                            StringBuilder title = new StringBuilder();
+                            var title = new StringBuilder();
                             GrowlHelper.NotifyType nt;
                             if (SettingManager.Common.DispUsername)
                             {
@@ -1806,7 +1756,7 @@ namespace OpenTween
                                 title.AppendFormat(Properties.Resources.RefreshTimeline_NotifyText, addCount);
                                 nt = GrowlHelper.NotifyType.Notify;
                             }
-                            string bText = sb.ToString();
+                            var bText = sb.ToString();
                             if (string.IsNullOrEmpty(bText)) return;
 
                             var image = this.IconCache.TryGetFromCache(post.ImageUrl);
@@ -1815,10 +1765,10 @@ namespace OpenTween
                     }
                     else
                     {
-                        StringBuilder sb = new StringBuilder();
-                        bool reply = false;
-                        bool dm = false;
-                        foreach (PostClass post in notifyPosts)
+                        var sb = new StringBuilder();
+                        var reply = false;
+                        var dm = false;
+                        foreach (var post in notifyPosts)
                         {
                             if (post.IsReply && !post.IsExcludeReply) reply = true;
                             if (post.IsDm) dm = true;
@@ -1836,7 +1786,7 @@ namespace OpenTween
 
                         }
                         //if (SettingDialog.DispUsername) { NotifyIcon1.BalloonTipTitle = tw.Username + " - "; } else { NotifyIcon1.BalloonTipTitle = ""; }
-                        StringBuilder title = new StringBuilder();
+                        var title = new StringBuilder();
                         ToolTipIcon ntIcon;
                         if (SettingManager.Common.DispUsername)
                         {
@@ -1874,7 +1824,7 @@ namespace OpenTween
                             title.Append(" ");
                             title.AppendFormat(Properties.Resources.RefreshTimeline_NotifyText, addCount);
                         }
-                        string bText = sb.ToString();
+                        var bText = sb.ToString();
                         if (string.IsNullOrEmpty(bText)) return;
                         //NotifyIcon1.BalloonTipText = sb.ToString();
                         //NotifyIcon1.ShowBalloonTip(500);
@@ -1891,12 +1841,12 @@ namespace OpenTween
             {
                 try
                 {
-                    string dir = Application.StartupPath;
+                    var dir = Application.StartupPath;
                     if (Directory.Exists(Path.Combine(dir, "Sounds")))
                     {
                         dir = Path.Combine(dir, "Sounds");
                     }
-                    using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, soundFile)))
+                    using (var player = new SoundPlayer(Path.Combine(dir, soundFile)))
                     {
                         player.Play();
                     }
@@ -1932,11 +1882,12 @@ namespace OpenTween
 
             var post = this.CurrentPost;
             this._statuses.SetReadAllTab(post.StatusId, read: true);
+
             //キャッシュの書き換え
             ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色)
 
-            ColorizeList();
-            _colorize = true;
+            this.colorizeDebouncer.Call();
+            this.selectionDebouncer.Call();
         }
 
         private void ChangeCacheStyleRead(bool Read, int Index)
@@ -1961,17 +1912,21 @@ namespace OpenTween
         private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView DList)
         {
             Font fnt;
+            string star;
             //フォント
             if (Read)
             {
                 fnt = _fntReaded;
-                Item.SubItems[5].Text = "";
+                star = "";
             }
             else
             {
                 fnt = _fntUnread;
-                Item.SubItems[5].Text = "★";
+                star = "★";
             }
+            if (Item.SubItems[5].Text != star)
+                Item.SubItems[5].Text = star;
+
             //文字色
             Color cl;
             if (Post.IsFav)
@@ -1995,9 +1950,9 @@ namespace OpenTween
             {
                 DList.Update();
                 if (SettingManager.Common.UseUnreadStyle)
-                    DList.ChangeItemFontAndColor(Item.Index, cl, fnt);
+                    DList.ChangeItemFontAndColor(Item, cl, fnt);
                 else
-                    DList.ChangeItemForeColor(Item.Index, cl);
+                    DList.ChangeItemForeColor(Item, cl);
                 //if (_itemCache != null) DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, false);
             }
         }
@@ -2018,16 +1973,19 @@ namespace OpenTween
             if (listCache == null)
                 return;
 
-            var index = listCache.StartIndex;
             var listView = (DetailsListView)listCache.TargetList;
-            foreach (var cachedPost in listCache.Post)
+
+            // ValidateRectが呼ばれる前に選択色などの描画を済ませておく
+            listView.Update();
+
+            foreach (var (listViewItem, cachedPost) in listCache.Cache)
             {
                 var backColor = this.JudgeColor(_post, cachedPost);
-                listView.ChangeItemBackColor(index++, backColor);
+                listView.ChangeItemBackColor(listViewItem, backColor);
             }
         }
 
-        private void ColorizeList(ListViewItem Item, int Index)
+        private void ColorizeList(ListViewItem Item, PostClass post, int Index)
         {
             //Index:更新対象のListviewItem.Index。Colorを返す。
             //-1は全キャッシュ。Colorは返さない(ダミーを戻す)
@@ -2037,14 +1995,12 @@ namespace OpenTween
             else
                 _post = this.CurrentPost;
 
-            PostClass tPost = GetCurTabPost(Index);
-
             if (_post == null) return;
 
             if (Item.Index == -1)
-                Item.BackColor = JudgeColor(_post, tPost);
+                Item.BackColor = JudgeColor(_post, post);
             else
-                this.CurrentListView.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost));
+                this.CurrentListView.ChangeItemBackColor(Item, JudgeColor(_post, post));
         }
 
         private Color JudgeColor(PostClass BasePost, PostClass TargetPost)
@@ -2065,7 +2021,7 @@ namespace OpenTween
             else if (TargetPost.ReplyToList.Any(x => x.UserId == BasePost.UserId))
                 //その人への返信
                 cl = _clAtTarget;
-            else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase))
+            else if (TargetPost.UserId == BasePost.UserId)
                 //発言者
                 cl = _clTarget;
             else
@@ -2119,7 +2075,7 @@ namespace OpenTween
             var currentPost = this.CurrentPost;
             if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", currentPost.ScreenName, currentPost.TextFromApi))
             {
-                DialogResult rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine),
+                var rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine),
                                                                "Retweet",
                                                                MessageBoxButtons.YesNoCancel,
                                                                MessageBoxIcon.Question);
@@ -2224,7 +2180,7 @@ namespace OpenTween
             //Google検索(試験実装)
             if (StatusText.Text.StartsWith("Google:", StringComparison.OrdinalIgnoreCase) && StatusText.Text.Trim().Length > 7)
             {
-                string tmp = string.Format(Properties.Resources.SearchItem2Url, Uri.EscapeDataString(StatusText.Text.Substring(7)));
+                var tmp = string.Format(Properties.Resources.SearchItem2Url, Uri.EscapeDataString(StatusText.Text.Substring(7)));
                 await this.OpenUriInBrowserAsync(tmp);
             }
 
@@ -2250,7 +2206,7 @@ namespace OpenTween
                 _hookGlobalHotkey.UnregisterAllOriginalHotkey();
                 _ignoreConfigSave = true;
                 MyCommon._endingFlag = true;
-                TimerTimeline.Enabled = false;
+                this.timelineScheduler.Enabled = false;
                 TimerRefreshIcon.Enabled = false;
             }
         }
@@ -2307,6 +2263,7 @@ namespace OpenTween
         private async Task RefreshTabAsync(TabModel tab, bool backward)
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
 
             try
             {
@@ -2360,6 +2317,7 @@ namespace OpenTween
         private async Task FavAddAsync(long statusId, TabModel tab)
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
 
             try
             {
@@ -2473,13 +2431,14 @@ namespace OpenTween
 
                 var currentPost = this.CurrentPost;
                 if (currentPost != null && statusId == currentPost.StatusId)
-                    await this.DispSelectedPost(true); // 選択アイテム再表示
+                    this.DispSelectedPost(true); // 選択アイテム再表示
             }
         }
 
         private async Task FavRemoveAsync(IReadOnlyList<long> statusIds, TabModel tab)
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
 
             try
             {
@@ -2588,7 +2547,7 @@ namespace OpenTween
 
                     var currentPost = this.CurrentPost;
                     if (currentPost != null && successIds.Contains(currentPost.StatusId))
-                        await this.DispSelectedPost(true); // 選択アイテム再表示
+                        this.DispSelectedPost(true); // 選択アイテム再表示
                 }
             }
         }
@@ -2596,6 +2555,7 @@ namespace OpenTween
         private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadService uploadService, IMediaItem[] uploadItems)
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
 
             try
             {
@@ -2742,6 +2702,7 @@ namespace OpenTween
         private async Task RetweetAsync(IReadOnlyList<long> statusIds)
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
 
             try
             {
@@ -2821,6 +2782,8 @@ namespace OpenTween
         private async Task RefreshFollowerIdsAsync()
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
+
             try
             {
                 this.StatusLabel.Text = Properties.Resources.UpdateFollowersMenuItem1_ClickText1;
@@ -2846,6 +2809,8 @@ namespace OpenTween
         private async Task RefreshNoRetweetIdsAsync()
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
+
             try
             {
                 await this.tw.RefreshNoRetweetIds();
@@ -2865,6 +2830,8 @@ namespace OpenTween
         private async Task RefreshBlockIdsAsync()
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
+
             try
             {
                 this.StatusLabel.Text = Properties.Resources.UpdateBlockUserText1;
@@ -2886,6 +2853,8 @@ namespace OpenTween
         private async Task RefreshTwitterConfigurationAsync()
         {
             await this.workerSemaphore.WaitAsync();
+            this.RefreshTasktrayIcon();
+
             try
             {
                 await this.tw.RefreshConfiguration();
@@ -3051,7 +3020,7 @@ namespace OpenTween
             var listCache = this._listItemCache;
             if (listCache != null)
             {
-                if (listCache.TryGetValue(Index, out var item, out var post))
+                if (listCache.TryGetValue(Index, out _, out var post))
                     return post;
             }
 
@@ -3084,7 +3053,7 @@ namespace OpenTween
                     _mySpDis = this.SplitContainer1.SplitterDistance;
                     _mySpDis3 = this.SplitContainer3.SplitterDistance;
                     if (StatusText.Multiline) _mySpDis2 = this.StatusText.Height;
-                    ModifySettingLocal = true;
+                    this.MarkSettingLocalModified();
                 }
             }
         }
@@ -3203,7 +3172,7 @@ namespace OpenTween
             }
             list.Refresh();
 
-            this.ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void TweenMain_LocationChanged(object sender, EventArgs e)
@@ -3211,7 +3180,7 @@ namespace OpenTween
             if (this.WindowState == FormWindowState.Normal && !_initialLayout)
             {
                 _myLoc = this.DesktopLocation;
-                ModifySettingLocal = true;
+                this.MarkSettingLocalModified();
             }
         }
 
@@ -3515,7 +3484,7 @@ namespace OpenTween
 
         private DialogResult ShowSettingDialog(bool showTaskbarIcon = false)
         {
-            DialogResult result = DialogResult.Abort;
+            var result = DialogResult.Abort;
 
             using (var settingDialog = new AppendSettingDialog())
             {
@@ -3727,7 +3696,7 @@ namespace OpenTween
 
                         foreach (TabPage tp in ListTab.TabPages)
                         {
-                            DetailsListView lst = (DetailsListView)tp.Tag;
+                            var lst = (DetailsListView)tp.Tag;
 
                             using (ControlTransaction.Update(lst))
                             {
@@ -3758,7 +3727,7 @@ namespace OpenTween
                     if (SettingManager.Common.HotkeyEnabled)
                     {
                         ///グローバルホットキーの登録。設定で変更可能にするかも
-                        HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
+                        var modKey = HookGlobalHotkey.ModKeys.None;
                         if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt)
                             modKey |= HookGlobalHotkey.ModKeys.Alt;
                         if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control)
@@ -3895,8 +3864,8 @@ namespace OpenTween
                 }
             }
             //ユニークなタブ名生成
-            string tabName = searchWord;
-            for (int i = 0; i <= 100; i++)
+            var tabName = searchWord;
+            for (var i = 0; i <= 100; i++)
             {
                 if (_statuses.ContainsTab(tabName))
                     tabName += "_";
@@ -3911,7 +3880,7 @@ namespace OpenTween
             ListTab.SelectedIndex = this._statuses.Tabs.Count - 1;
             //検索条件の設定
             var tabPage = this.CurrentTabPage;
-            ComboBox cmb = (ComboBox)tabPage.Controls["panelSearch"].Controls["comboSearch"];
+            var cmb = (ComboBox)tabPage.Controls["panelSearch"].Controls["comboSearch"];
             cmb.Items.Add(searchWord);
             cmb.Text = searchWord;
             SaveConfigsTabs();
@@ -3948,7 +3917,7 @@ namespace OpenTween
                 }
             }
             //ユニークなタブ名生成
-            string tabName = "user:" + user;
+            var tabName = "user:" + user;
             while (_statuses.ContainsTab(tabName))
             {
                 tabName += "_";
@@ -3976,7 +3945,7 @@ namespace OpenTween
             var _tabPage = new TabPage();
             var _listCustom = new DetailsListView();
 
-            int cnt = this._statuses.Tabs.Count;
+            var cnt = this._statuses.Tabs.Count;
 
             ///ToDo:Create and set controls follow tabtypes
 
@@ -4013,7 +3982,7 @@ namespace OpenTween
                         label.Text = userTab.ScreenName + "'s Timeline";
                     }
                     label.TextAlign = ContentAlignment.MiddleLeft;
-                    using (ComboBox tmpComboBox = new ComboBox())
+                    using (var tmpComboBox = new ComboBox())
                     {
                         label.Height = tmpComboBox.Height;
                     }
@@ -4175,7 +4144,7 @@ namespace OpenTween
 
             if (confirm)
             {
-                string tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine);
+                var tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine);
                 if (MessageBox.Show(tmp, TabName + " " + Properties.Resources.RemoveSpecifiedTabText2,
                                  MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                 {
@@ -4192,7 +4161,7 @@ namespace OpenTween
             SetListProperty();   //他のタブに列幅等を反映
 
             //オブジェクトインスタンスの削除
-            DetailsListView _listCustom = (DetailsListView)_tabPage.Tag;
+            var _listCustom = (DetailsListView)_tabPage.Tag;
             _tabPage.Tag = null;
 
             using (ControlTransaction.Layout(this.SplitContainer1.Panel1, false))
@@ -4212,14 +4181,14 @@ namespace OpenTween
                 // 後付けのコントロールを破棄
                 if (tabInfo.TabType == MyCommon.TabUsageType.UserTimeline || tabInfo.TabType == MyCommon.TabUsageType.Lists)
                 {
-                    using (Control label = _tabPage.Controls["labelUser"])
+                    using (var label = _tabPage.Controls["labelUser"])
                     {
                         _tabPage.Controls.Remove(label);
                     }
                 }
                 else if (tabInfo.TabType == MyCommon.TabUsageType.PublicSearch)
                 {
-                    using (Control pnl = _tabPage.Controls["panelSearch"])
+                    using (var pnl = _tabPage.Controls["panelSearch"])
                     {
                         pnl.Enter -= SearchControls_Enter;
                         pnl.Leave -= SearchControls_Leave;
@@ -4300,8 +4269,8 @@ namespace OpenTween
 
             if (!SettingManager.Common.TabMouseLock && e.Button == MouseButtons.Left && _tabDrag)
             {
-                string tn = "";
-                Rectangle dragEnableRectangle = new Rectangle(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), _tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height);
+                var tn = "";
+                var dragEnableRectangle = new Rectangle(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), _tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height);
                 if (!dragEnableRectangle.Contains(e.Location))
                 {
                     //タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。
@@ -4322,7 +4291,7 @@ namespace OpenTween
                 _tabDrag = false;
             }
 
-            Point cpos = new Point(e.X, e.Y);
+            var cpos = new Point(e.X, e.Y);
             foreach (var (tab, index) in this._statuses.Tabs.WithIndex())
             {
                 var rect = ListTab.GetTabRect(index);
@@ -4334,7 +4303,7 @@ namespace OpenTween
             }
         }
 
-        private async void ListTab_SelectedIndexChanged(object sender, EventArgs e)
+        private void ListTab_SelectedIndexChanged(object sender, EventArgs e)
         {
             //_curList.Refresh();
             SetMainWindowTitle();
@@ -4344,7 +4313,7 @@ namespace OpenTween
                 this.Tag = ListTab.Tag;
             TabMenuControl(this.CurrentTabName);
             this.PushSelectPostChain();
-            await DispSelectedPost();
+            DispSelectedPost();
         }
 
         private void SetListProperty()
@@ -4353,10 +4322,10 @@ namespace OpenTween
 
             var currentListView = this.CurrentListView;
 
-            int[] dispOrder = new int[currentListView.Columns.Count];
-            for (int i = 0; i < currentListView.Columns.Count; i++)
+            var dispOrder = new int[currentListView.Columns.Count];
+            for (var i = 0; i < currentListView.Columns.Count; i++)
             {
-                for (int j = 0; j < currentListView.Columns.Count; j++)
+                for (var j = 0; j < currentListView.Columns.Count; j++)
                 {
                     if (currentListView.Columns[j].DisplayIndex == i)
                     {
@@ -4374,8 +4343,8 @@ namespace OpenTween
 
                 if (tb.Tag != null && tb.Controls.Count > 0)
                 {
-                    DetailsListView lst = (DetailsListView)tb.Tag;
-                    for (int i = 0; i < lst.Columns.Count; i++)
+                    var lst = (DetailsListView)tb.Tag;
+                    for (var i = 0; i < lst.Columns.Count; i++)
                     {
                         lst.Columns[dispOrder[i]].DisplayIndex = i;
                         lst.Columns[i].Width = currentListView.Columns[i].Width;
@@ -4392,9 +4361,10 @@ namespace OpenTween
             {
                 if (!SettingManager.Common.UseAtIdSupplement) return;
                 //@マーク
-                int cnt = AtIdSupl.ItemCount;
+                var cnt = AtIdSupl.ItemCount;
                 ShowSuplDialog(StatusText, AtIdSupl);
-                if (cnt != AtIdSupl.ItemCount) ModifySettingAtId = true;
+                if (cnt != AtIdSupl.ItemCount)
+                    this.MarkSettingAtIdModified();
                 e.Handled = true;
             }
             else if (e.KeyChar == '#')
@@ -4423,9 +4393,9 @@ namespace OpenTween
                 dialog.ShowDialog();
             }
             this.TopMost = SettingManager.Common.AlwaysTop;
-            int selStart = owner.SelectionStart;
-            string fHalf = "";
-            string eHalf = "";
+            var selStart = owner.SelectionStart;
+            var fHalf = "";
+            var eHalf = "";
             if (dialog.DialogResult == DialogResult.OK)
             {
                 if (!string.IsNullOrEmpty(dialog.inputText))
@@ -4468,8 +4438,8 @@ namespace OpenTween
             {
                 if (e.KeyCode == Keys.Space || e.KeyCode == Keys.ProcessKey)
                 {
-                    bool isSpace = false;
-                    foreach (char c in StatusText.Text)
+                    var isSpace = false;
+                    foreach (var c in StatusText.Text)
                     {
                         if (c == ' ' || c == ' ')
                         {
@@ -4495,7 +4465,7 @@ namespace OpenTween
         private void StatusText_TextChanged(object sender, EventArgs e)
         {
             //文字数カウント
-            int pLen = this.GetRestStatusCount(this.FormatStatusTextExtended(this.StatusText.Text));
+            var pLen = this.GetRestStatusCount(this.FormatStatusTextExtended(this.StatusText.Text));
             lblLen.Text = pLen.ToString();
             if (pLen < 0)
             {
@@ -4545,7 +4515,7 @@ namespace OpenTween
         /// </summary>
         private string RemoveAutoPopuratedMentions(string statusText, out long[] autoPopulatedUserIds)
         {
-            List<long> _autoPopulatedUserIds = new List<long>();
+            var _autoPopulatedUserIds = new List<long>();
 
             var replyToPost = this.inReplyTo != null ? this._statuses[this.inReplyTo.Value.StatusId] : null;
             if (replyToPost != null)
@@ -4596,7 +4566,7 @@ namespace OpenTween
         }
 
         private string FormatStatusTextExtended(string statusText)
-            => this.FormatStatusTextExtended(statusText, out var autoPopulatedUserIds, out var attachmentUrl);
+            => this.FormatStatusTextExtended(statusText, out _, out _);
 
         /// <summary>
         /// <see cref="FormatStatusText"/> に加えて、拡張モードで140字にカウントされない文字列の除去を行います
@@ -4746,7 +4716,7 @@ namespace OpenTween
             var listCache = this._listItemCache;
             if (listCache?.TargetList == sender)
             {
-                if (listCache.TryGetValue(e.ItemIndex, out var item, out var cacheItemPost))
+                if (listCache.TryGetValue(e.ItemIndex, out var item, out _))
                 {
                     e.Item = item;
                     return;
@@ -4796,8 +4766,7 @@ namespace OpenTween
                 TargetList = this.CurrentListView,
                 StartIndex = startIndex,
                 EndIndex = endIndex,
-                Post = posts,
-                ListItem = listItems,
+                Cache = Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray(),
             };
 
             Interlocked.Exchange(ref this._listItemCache, listCache);
@@ -4811,7 +4780,7 @@ namespace OpenTween
 
         private ListViewItem CreateItem(TabModel tab, PostClass Post, int Index)
         {
-            StringBuilder mk = new StringBuilder();
+            var mk = new StringBuilder();
             //if (Post.IsDeleted) mk.Append("×");
             //if (Post.IsMark) mk.Append("♪");
             //if (Post.IsProtect) mk.Append("Ю");
@@ -4845,7 +4814,7 @@ namespace OpenTween
             itm.StateIndex = Post.StateIndex;
             itm.Tag = Post;
 
-            bool read = Post.IsRead;
+            var read = Post.IsRead;
             // 未読管理していなかったら既読として扱う
             if (!tab.UnreadManage || !SettingManager.Common.UnreadManage)
                 read = true;
@@ -4853,7 +4822,7 @@ namespace OpenTween
             ChangeItemStyleRead(read, itm, Post, null);
 
             if (tab.TabName == this.CurrentTabName)
-                this.ColorizeList(itm, Index);
+                this.ColorizeList(itm, Post, Index);
 
             return itm;
         }
@@ -4905,7 +4874,7 @@ namespace OpenTween
             if (e.State == 0) return;
             e.DrawDefault = false;
 
-            SolidBrush brs2 = null;
+            SolidBrush brs2;
             if (!e.Item.Selected)     //e.ItemStateでうまく判定できない???
             {
                 if (e.Item.BackColor == _clSelf)
@@ -4947,14 +4916,14 @@ namespace OpenTween
 
                 RectangleF rct = e.Bounds;
                 rct.Width = e.Header.Width;
-                int fontHeight = e.Item.Font.Height;
+                var fontHeight = e.Item.Font.Height;
                 if (_iconCol)
                 {
                     rct.Y += fontHeight;
                     rct.Height -= fontHeight;
                 }
 
-                int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff));
+                var drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff));
 
                 //if (heightDiff > fontHeight * 0.7)
                 //{
@@ -4987,17 +4956,17 @@ namespace OpenTween
 
                 if (rct.Width > 0)
                 {
-                    Color color = (!e.Item.Selected) ? e.Item.ForeColor :   //選択されていない行
+                    var color = (!e.Item.Selected) ? e.Item.ForeColor :   //選択されていない行
                         (((Control)sender).Focused) ? _clHighLight :        //選択中の行
                         _clUnread;
 
                     if (_iconCol)
                     {
-                        Rectangle rctB = e.Bounds;
+                        var rctB = e.Bounds;
                         rctB.Width = e.Header.Width;
                         rctB.Height = fontHeight;
 
-                        using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
+                        using (var fnt = new Font(e.Item.Font, FontStyle.Bold))
                         {
                             TextRenderer.DrawText(e.Graphics,
                                                     post.IsDeleted ? "(DELETED)" : post.TextSingleLine,
@@ -5062,10 +5031,10 @@ namespace OpenTween
         {
             if (_iconSz == 0) return;
 
-            ImageListViewItem item = (ImageListViewItem)e.Item;
+            var item = (ImageListViewItem)e.Item;
 
             //e.Bounds.Leftが常に0を指すから自前で計算
-            Rectangle itemRect = item.Bounds;
+            var itemRect = item.Bounds;
             var col0 = e.Item.ListView.Columns[0];
             itemRect.Width = col0.Width;
 
@@ -5113,7 +5082,7 @@ namespace OpenTween
 
             if (item.StateIndex > -1)
             {
-                Rectangle stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect);
+                var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect);
                 if (stateRect.Width > 0)
                 {
                     //e.Graphics.FillRectangle(Brushes.White, stateRect);
@@ -5371,7 +5340,7 @@ namespace OpenTween
 
         private void AboutMenuItem_Click(object sender, EventArgs e)
         {
-            using (TweenAboutBox about = new TweenAboutBox())
+            using (var about = new TweenAboutBox())
             {
                 about.ShowDialog(this);
             }
@@ -5386,7 +5355,7 @@ namespace OpenTween
                 return;
 
             TabModel foundTab = null;
-            int foundIndex = 0;
+            var foundIndex = 0;
 
             DetailsListView lst = null;
 
@@ -5567,7 +5536,7 @@ namespace OpenTween
                     else if (dialog.SkipButtonPressed)
                     {
                         SettingManager.Common.SkipUpdateVersion = versionInfo.Version;
-                        this.ModifySettingCommon = true;
+                        this.MarkSettingCommonModified();
                     }
                 }
             }
@@ -5583,10 +5552,8 @@ namespace OpenTween
             }
         }
 
-        private async Task Colorize()
+        private void UpdateSelectedPost()
         {
-            _colorize = false;
-            await this.DispSelectedPost();
             //件数関連の場合、タイトル即時書き換え
             if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None &&
                SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post &&
@@ -5598,11 +5565,11 @@ namespace OpenTween
             if (!StatusLabelUrl.Text.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                 SetStatusLabelUrl();
 
-            foreach (var (tab, index) in this._statuses.Tabs.WithIndex())
+            if (SettingManager.Common.TabIconDisp)
             {
-                if (tab.UnreadCount == 0)
+                foreach (var (tab, index) in this._statuses.Tabs.WithIndex())
                 {
-                    if (SettingManager.Common.TabIconDisp)
+                    if (tab.UnreadCount == 0)
                     {
                         var tabPage = this.ListTab.TabPages[index];
                         if (tabPage.ImageIndex == 0)
@@ -5610,13 +5577,18 @@ namespace OpenTween
                     }
                 }
             }
-            if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
+            else
+            {
+                this.ListTab.Refresh();
+            }
+
+            this.DispSelectedPost();
         }
 
         public string createDetailHtml(string orgdata)
             => detailHtmlFormatHeader + orgdata + detailHtmlFormatFooter;
 
-        private Task DispSelectedPost()
+        private void DispSelectedPost()
             => this.DispSelectedPost(false);
 
         private PostClass displayPost = new PostClass();
@@ -5626,7 +5598,7 @@ namespace OpenTween
         /// </summary>
         private CancellationTokenSource thumbnailTokenSource = null;
 
-        private async Task DispSelectedPost(bool forceupdate)
+        private void DispSelectedPost(bool forceupdate)
         {
             var currentPost = this.CurrentPost;
             if (currentPost == null)
@@ -5654,11 +5626,17 @@ namespace OpenTween
                 loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(currentPost, token));
             }
 
-            try
+            async Task delayedTasks()
             {
-                await Task.WhenAll(loadTasks);
+                try
+                {
+                    await Task.WhenAll(loadTasks);
+                }
+                catch (OperationCanceledException) { }
             }
-            catch (OperationCanceledException) { }
+
+            // サムネイルの読み込みを待たずに次に選択されたツイートを表示するため await しない
+            _ = delayedTasks();
         }
 
         private async void MatomeMenuItem_Click(object sender, EventArgs e)
@@ -5675,7 +5653,7 @@ namespace OpenTween
             var tab = this.CurrentTab;
             if (tab.TabType == MyCommon.TabUsageType.PublicSearch)
             {
-                Control pnl = this.CurrentTabPage.Controls["panelSearch"];
+                var pnl = this.CurrentTabPage.Controls["panelSearch"];
                 if (pnl.Controls["comboSearch"].Focused ||
                     pnl.Controls["comboLang"].Focused ||
                     pnl.Controls["buttonSearch"].Focused) return;
@@ -5869,7 +5847,7 @@ namespace OpenTween
 
                 ShortcutCommand.Create(Keys.Control | Keys.Home, Keys.Control | Keys.End)
                     .FocusedOn(FocusedControl.ListTab)
-                    .Do(() => this._colorize = true, preventDefault: false),
+                    .Do(() => this.selectionDebouncer.Call(), preventDefault: false),
 
                 ShortcutCommand.Create(Keys.Control | Keys.N)
                     .FocusedOn(FocusedControl.ListTab)
@@ -6125,21 +6103,22 @@ namespace OpenTween
                     .Do(() => {
                         if (StatusText.SelectionStart > 0)
                         {
-                            int endidx = StatusText.SelectionStart - 1;
-                            string startstr = "";
-                            for (int i = StatusText.SelectionStart - 1; i >= 0; i--)
+                            var endidx = StatusText.SelectionStart - 1;
+                            var startstr = "";
+                            for (var i = StatusText.SelectionStart - 1; i >= 0; i--)
                             {
-                                char c = StatusText.Text[i];
-                                if (Char.IsLetterOrDigit(c) || c == '_')
+                                var c = StatusText.Text[i];
+                                if (char.IsLetterOrDigit(c) || c == '_')
                                 {
                                     continue;
                                 }
                                 if (c == '@')
                                 {
                                     startstr = StatusText.Text.Substring(i + 1, endidx - i);
-                                    int cnt = AtIdSupl.ItemCount;
+                                    var cnt = AtIdSupl.ItemCount;
                                     ShowSuplDialog(StatusText, AtIdSupl, startstr.Length + 1, startstr);
-                                    if (AtIdSupl.ItemCount != cnt) ModifySettingAtId = true;
+                                    if (AtIdSupl.ItemCount != cnt)
+                                        this.MarkSettingAtIdModified();
                                 }
                                 else if (c == '#')
                                 {
@@ -6250,7 +6229,7 @@ namespace OpenTween
 
         private void GoNextTab(bool forward)
         {
-            int idx = this._statuses.SelectedTabIndex;
+            var idx = this._statuses.SelectedTabIndex;
             var tabCount = this._statuses.Tabs.Count;
             if (forward)
             {
@@ -6267,10 +6246,9 @@ namespace OpenTween
 
         private void CopyStot()
         {
-            string clstr = "";
-            StringBuilder sb = new StringBuilder();
+            var sb = new StringBuilder();
             var tab = this.CurrentTab;
-            bool IsProtected = false;
+            var IsProtected = false;
             var isDm = tab.TabType == MyCommon.TabUsageType.DirectMessage;
             foreach (var post in tab.SelectedPosts)
             {
@@ -6293,7 +6271,7 @@ namespace OpenTween
             }
             if (sb.Length > 0)
             {
-                clstr = sb.ToString();
+                var clstr = sb.ToString();
                 try
                 {
                     Clipboard.SetDataObject(clstr, false, 5, 100);
@@ -6336,9 +6314,9 @@ namespace OpenTween
 
             var selectedIndex = tab.SelectedIndex;
 
-            int fIdx = 0;
-            int toIdx = 0;
-            int stp = 1;
+            int fIdx;
+            int toIdx;
+            int stp;
 
             if (forward)
             {
@@ -6349,7 +6327,8 @@ namespace OpenTween
                 else
                 {
                     fIdx = selectedIndex + 1;
-                    if (fIdx > tab.AllCount - 1) return;
+                    if (fIdx > tab.AllCount - 1)
+                        return;
                 }
                 toIdx = tab.AllCount;
                 stp = 1;
@@ -6363,13 +6342,14 @@ namespace OpenTween
                 else
                 {
                     fIdx = selectedIndex - 1;
-                    if (fIdx < 0) return;
+                    if (fIdx < 0)
+                        return;
                 }
                 toIdx = -1;
                 stp = -1;
             }
 
-            for (int idx = fIdx; idx != toIdx; idx += stp)
+            for (var idx = fIdx; idx != toIdx; idx += stp)
             {
                 if (tab[idx].IsFav)
                 {
@@ -6424,7 +6404,7 @@ namespace OpenTween
                 stp = 1;
             }
 
-            for (int tabidx = fIdx; tabidx != toIdx; tabidx += stp)
+            for (var tabidx = fIdx; tabidx != toIdx; tabidx += stp)
             {
                 var targetTab = this._statuses.Tabs[tabidx];
 
@@ -6471,7 +6451,7 @@ namespace OpenTween
                 stp = -1;
             }
 
-            string name = "";
+            string name;
             if (currentPost.RetweetedId == null)
             {
                 name = currentPost.ScreenName;
@@ -6480,7 +6460,7 @@ namespace OpenTween
             {
                 name = currentPost.RetweetedBy;
             }
-            for (int idx = fIdx; idx != toIdx; idx += stp)
+            for (var idx = fIdx; idx != toIdx; idx += stp)
             {
                 var post = tab[idx];
                 if (post.RetweetedId == null)
@@ -6543,7 +6523,7 @@ namespace OpenTween
                 if (_anchorPost == null) return;
             }
 
-            for (int idx = fIdx; idx != toIdx; idx += stp)
+            for (var idx = fIdx; idx != toIdx; idx += stp)
             {
                 var post = tab[idx];
                 if (post.ScreenName == _anchorPost.ScreenName ||
@@ -6566,7 +6546,7 @@ namespace OpenTween
         private void GoAnchor()
         {
             if (_anchorPost == null) return;
-            int idx = this.CurrentTab.IndexOf(_anchorPost.StatusId);
+            var idx = this.CurrentTab.IndexOf(_anchorPost.StatusId);
             if (idx == -1) return;
 
             var listView = this.CurrentListView;
@@ -6658,7 +6638,7 @@ namespace OpenTween
         {
             var listView = this.CurrentListView;
             if (listView.SelectedIndices.Count == 0) return;
-            int idx = listView.SelectedIndices[0];
+            var idx = listView.SelectedIndices[0];
             if (_statuses.SortOrder == SortOrder.Ascending)
             {
                 listView.EnsureVisible(listView.VirtualListSize - 1);
@@ -6755,7 +6735,7 @@ namespace OpenTween
 
             var tabIndex = this._statuses.Tabs.IndexOf(inReplyToTabName);
             var tabPage = this.ListTab.TabPages[tabIndex];
-            DetailsListView listView = (DetailsListView)tabPage.Tag;
+            var listView = (DetailsListView)tabPage.Tag;
 
             if (this.CurrentTabName != inReplyToTabName)
             {
@@ -6789,17 +6769,17 @@ namespace OpenTween
                     try
                     {
                         var postList = posts.ToList();
-                        for (int i = postList.Count - 1; i >= 0; i--)
+                        for (var i = postList.Count - 1; i >= 0; i--)
                         {
-                            int index = i;
-                            if (postList.FindIndex((pst) => { return pst.Post.StatusId == postList[index].Post.StatusId; }) != index)
+                            var index = i;
+                            if (postList.FindIndex(pst => pst.Post.StatusId == postList[index].Post.StatusId) != index)
                             {
                                 postList.RemoveAt(index);
                             }
                         }
                         var currentIndex = this.CurrentTab.SelectedIndex;
-                        var post = postList.FirstOrDefault((pst) => { return pst.Tab == curTabClass && isForward ? pst.Index > currentIndex : pst.Index < currentIndex; });
-                        if (post == null) post = postList.FirstOrDefault((pst) => { return pst.Tab != curTabClass; });
+                        var post = postList.FirstOrDefault(pst => pst.Tab == curTabClass && isForward ? pst.Index > currentIndex : pst.Index < currentIndex);
+                        if (post == null) post = postList.FirstOrDefault(pst => pst.Tab != curTabClass);
                         if (post == null) post = postList.First();
                         var tabIndex = this._statuses.Tabs.IndexOf(post.Tab);
                         this.ListTab.SelectedIndex = tabIndex;
@@ -6841,7 +6821,7 @@ namespace OpenTween
                 }
                 else
                 {
-                    ReplyChain chainHead = replyChains.Pop();
+                    var chainHead = replyChains.Pop();
                     if (chainHead.InReplyToId == currentPost.StatusId)
                     {
                         var tab = chainHead.OriginalTab;
@@ -6945,7 +6925,7 @@ namespace OpenTween
             var currentTab = this.CurrentTab;
             var currentPost = this.CurrentPost;
 
-            int count = this.selectPostChains.Count;
+            var count = this.selectPostChains.Count;
             if (count > 0)
             {
                 var (tab, post) = this.selectPostChains.Peek();
@@ -6963,12 +6943,12 @@ namespace OpenTween
         {
             if (this.selectPostChains.Count <= 2000) return;
             var p = new Stack<(TabModel, PostClass)>(2000);
-            for (int i = 0; i < 2000; i++)
+            for (var i = 0; i < 2000; i++)
             {
                 p.Push(this.selectPostChains.Pop());
             }
             this.selectPostChains.Clear();
-            for (int i = 0; i < 2000; i++)
+            for (var i = 0; i < 2000; i++)
             {
                 this.selectPostChains.Push(p.Pop());
             }
@@ -7248,7 +7228,7 @@ namespace OpenTween
         {
             var tab = this.CurrentTab;
 
-            DialogResult rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine),
+            var rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine),
                     Properties.Resources.SaveLogMenuItem_ClickText2,
                     MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
             if (rslt == DialogResult.Cancel) return;
@@ -7263,15 +7243,15 @@ namespace OpenTween
             if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
             {
                 if (!SaveFileDialog1.ValidateNames) return;
-                using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
+                using (var sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
                 {
                     if (rslt == DialogResult.Yes)
                     {
                         //All
-                        for (int idx = 0; idx < tab.AllCount; idx++)
+                        for (var idx = 0; idx < tab.AllCount; idx++)
                         {
                             var post = tab[idx];
-                            string protect = "";
+                            var protect = "";
                             if (post.IsProtect) protect = "Protect";
                             sw.WriteLine(post.Nickname + "\t" +
                                      "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
@@ -7287,7 +7267,7 @@ namespace OpenTween
                     {
                         foreach (var post in this.CurrentTab.SelectedPosts)
                         {
-                            string protect = "";
+                            var protect = "";
                             if (post.IsProtect) protect = "Protect";
                             sw.WriteLine(post.Nickname + "\t" +
                                      "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
@@ -7308,7 +7288,7 @@ namespace OpenTween
         {
             //タブ名変更
             newTabName = null;
-            using (InputTabName inputName = new InputTabName())
+            using (var inputName = new InputTabName())
             {
                 inputName.TabName = origTabName;
                 inputName.ShowDialog();
@@ -7321,7 +7301,7 @@ namespace OpenTween
                 //新タブ名存在チェック
                 if (this._statuses.ContainsTab(newTabName))
                 {
-                    string tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabName);
+                    var tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabName);
                     MessageBox.Show(tmp, Properties.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                     return false;
                 }
@@ -7363,7 +7343,7 @@ namespace OpenTween
         }
 
         private void ListTab_DoubleClick(object sender, MouseEventArgs e)
-            => this.TabRename(this.CurrentTabName, out var _);
+            => this.TabRename(this.CurrentTabName, out _);
 
         private void ListTab_MouseDown(object sender, MouseEventArgs e)
         {
@@ -7399,13 +7379,13 @@ namespace OpenTween
             if (!e.Data.GetDataPresent(typeof(TabPage))) return;
 
             _tabDrag = false;
-            string tn = "";
-            bool bef = false;
-            Point cpos = new Point(e.X, e.Y);
-            Point spos = ListTab.PointToClient(cpos);
+            var tn = "";
+            var bef = false;
+            var cpos = new Point(e.X, e.Y);
+            var spos = ListTab.PointToClient(cpos);
             foreach (var (tab, index) in this._statuses.Tabs.WithIndex())
             {
-                Rectangle rect = ListTab.GetTabRect(index);
+                var rect = ListTab.GetTabRect(index);
                 if (rect.Contains(spos))
                 {
                     tn = tab.TabName;
@@ -7426,7 +7406,7 @@ namespace OpenTween
                 bef = false;
             }
 
-            TabPage tp = (TabPage)e.Data.GetData(typeof(TabPage));
+            var tp = (TabPage)e.Data.GetData(typeof(TabPage));
             if (tp.Text == tn) return;
 
             ReOrderTab(tp.Text, tn, bef);
@@ -7552,8 +7532,8 @@ namespace OpenTween
                         else
                         {
                             //1件選んでCtrl-Rの場合(返信先操作せず)
-                            int sidx = StatusText.SelectionStart;
-                            string id = "@" + post.ScreenName + " ";
+                            var sidx = StatusText.SelectionStart;
+                            var id = "@" + post.ScreenName + " ";
                             if (sidx > 0)
                             {
                                 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
@@ -7594,7 +7574,7 @@ namespace OpenTween
                     {
                         //Enter or DoubleClick
 
-                        string sTxt = StatusText.Text;
+                        var sTxt = StatusText.Text;
                         if (!sTxt.StartsWith(". ", StringComparison.Ordinal))
                         {
                             sTxt = ". " + sTxt;
@@ -7618,8 +7598,8 @@ namespace OpenTween
                         {
                             //複数ポスト選択
 
-                            string ids = "";
-                            int sidx = StatusText.SelectionStart;
+                            var ids = "";
+                            var sidx = StatusText.SelectionStart;
                             foreach (var post in selectedPosts)
                             {
                                 if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != tw.UserId)
@@ -7633,7 +7613,7 @@ namespace OpenTween
                                         if (!ids.Contains("@" + screenName + " ") &&
                                             !screenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
                                         {
-                                            Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
+                                            var m = Regex.Match(post.TextFromApi, "[@@](?<id>" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
                                             if (m.Success)
                                                 ids += "@" + m.Result("${id}") + " ";
                                             else
@@ -7676,8 +7656,8 @@ namespace OpenTween
                         {
                             //1件のみ選択のC-S-r(返信元付加する可能性あり)
 
-                            string ids = "";
-                            int sidx = StatusText.SelectionStart;
+                            var ids = "";
+                            var sidx = StatusText.SelectionStart;
                             var post = selectedPosts.Single();
                             if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != tw.UserId)
                             {
@@ -7688,7 +7668,7 @@ namespace OpenTween
                                 if (!ids.Contains("@" + screenName + " ") &&
                                     !screenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
                                 {
-                                    Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
+                                    var m = Regex.Match(post.TextFromApi, "[@@](?<id>" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
                                     if (m.Success)
                                         ids += "@" + m.Result("${id}") + " ";
                                     else
@@ -7739,101 +7719,74 @@ namespace OpenTween
         private void ListTab_MouseUp(object sender, MouseEventArgs e)
             => this._tabDrag = false;
 
-        private static int iconCnt = 0;
-        private static int blinkCnt = 0;
-        private static bool blink = false;
-        private static bool idle = false;
+        private int iconCnt = 0;
+        private int blinkCnt = 0;
+        private bool blink = false;
 
-        private async Task RefreshTasktrayIcon()
+        private void RefreshTasktrayIcon()
         {
-            if (_colorize)
-                await this.Colorize();
-
-            if (!TimerRefreshIcon.Enabled) return;
-            //Static usCheckCnt As int = 0
-
-            //Static iconDlListTopItem As ListViewItem = null
-
-            //if (((ListView)ListTab.SelectedTab.Tag).TopItem == iconDlListTopItem)
-            //    ((ImageDictionary)this.TIconDic).PauseGetImage = false;
-            //else
-            //    ((ImageDictionary)this.TIconDic).PauseGetImage = true;
-            //
-            //iconDlListTopItem = ((ListView)ListTab.SelectedTab.Tag).TopItem;
-
-            iconCnt += 1;
-            blinkCnt += 1;
-            //usCheckCnt += 1;
+            void EnableTasktrayAnimation()
+                => this.TimerRefreshIcon.Enabled = true;
 
-            //if (usCheckCnt > 300)    //1min
-            //{
-            //    usCheckCnt = 0;
-            //    if (!this.IsReceivedUserStream)
-            //    {
-            //        TraceOut("ReconnectUserStream");
-            //        tw.ReconnectUserStream();
-            //    }
-            //}
+            void DisableTasktrayAnimation()
+                => this.TimerRefreshIcon.Enabled = false;
 
-            var busy = this.workerSemaphore.CurrentCount != MAX_WORKER_THREADS;
-
-            if (iconCnt >= this.NIconRefresh.Length)
-            {
-                iconCnt = 0;
-            }
-            if (blinkCnt > 10)
+            var busyTasks = this.workerSemaphore.CurrentCount != MAX_WORKER_THREADS;
+            if (busyTasks)
             {
-                blinkCnt = 0;
-                //未保存の変更を保存
-                SaveConfigsAll(true);
-            }
+                iconCnt += 1;
+                if (iconCnt >= this.NIconRefresh.Length)
+                    iconCnt = 0;
 
-            if (busy)
-            {
                 NotifyIcon1.Icon = NIconRefresh[iconCnt];
-                idle = false;
                 _myStatusError = false;
+                EnableTasktrayAnimation();
                 return;
             }
 
-            TabModel tb = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
-            if (SettingManager.Common.ReplyIconState != MyCommon.REPLY_ICONSTATE.None && tb != null && tb.UnreadCount > 0)
+            var replyIconType = SettingManager.Common.ReplyIconState;
+            var reply = false;
+            if (replyIconType != MyCommon.REPLY_ICONSTATE.None)
             {
-                if (blinkCnt > 0) return;
-                blink = !blink;
-                if (blink || SettingManager.Common.ReplyIconState == MyCommon.REPLY_ICONSTATE.StaticIcon)
-                {
-                    NotifyIcon1.Icon = ReplyIcon;
-                }
-                else
-                {
-                    NotifyIcon1.Icon = ReplyIconBlink;
-                }
-                idle = false;
-                return;
+                var replyTab = this._statuses.GetTabByType<MentionsTabModel>();
+                if (replyTab != null && replyTab.UnreadCount > 0)
+                    reply = true;
             }
 
-            if (idle) return;
-            idle = true;
-            //優先度:エラー→オフライン→アイドル
-            //エラーは更新アイコンでクリアされる
-            if (_myStatusError)
+            if (replyIconType == MyCommon.REPLY_ICONSTATE.BlinkIcon && reply)
             {
-                NotifyIcon1.Icon = NIconAtRed;
+                blinkCnt += 1;
+                if (blinkCnt > 10)
+                    blinkCnt = 0;
+
+                if (blinkCnt == 0)
+                    blink = !blink;
+
+                NotifyIcon1.Icon = blink ? ReplyIconBlink : ReplyIcon;
+                EnableTasktrayAnimation();
                 return;
             }
-            if (_myStatusOnline)
-            {
+
+            DisableTasktrayAnimation();
+
+            iconCnt = 0;
+            blinkCnt = 0;
+            blink = false;
+
+            // 優先度:リプライ→エラー→オフライン→アイドル
+            // エラーは更新アイコンでクリアされる
+            if (replyIconType == MyCommon.REPLY_ICONSTATE.StaticIcon && reply)
+                NotifyIcon1.Icon = ReplyIcon;
+            else if (_myStatusError)
+                NotifyIcon1.Icon = NIconAtRed;
+            else if (_myStatusOnline)
                 NotifyIcon1.Icon = NIconAt;
-            }
             else
-            {
                 NotifyIcon1.Icon = NIconAtSmoke;
-            }
         }
 
-        private async void TimerRefreshIcon_Tick(object sender, EventArgs e)
-            => await this.RefreshTasktrayIcon(); // 200ms
+        private void TimerRefreshIcon_Tick(object sender, EventArgs e)
+            => this.RefreshTasktrayIcon(); // 200ms
 
         private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e)
         {
@@ -7855,17 +7808,17 @@ namespace OpenTween
             this.SoundFileTbComboBox.Items.Clear();
             SoundFileComboBox.Items.Add("");
             this.SoundFileTbComboBox.Items.Add("");
-            DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
+            var oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
             if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
             {
                 oDir = oDir.GetDirectories("Sounds")[0];
             }
-            foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
+            foreach (var oFile in oDir.GetFiles("*.wav"))
             {
                 SoundFileComboBox.Items.Add(oFile.Name);
                 this.SoundFileTbComboBox.Items.Add(oFile.Name);
             }
-            int idx = SoundFileComboBox.Items.IndexOf(tb.SoundFile);
+            var idx = SoundFileComboBox.Items.IndexOf(tb.SoundFile);
             if (idx == -1) idx = 0;
             SoundFileComboBox.SelectedIndex = idx;
             this.SoundFileTbComboBox.SelectedIndex = idx;
@@ -8018,7 +7971,7 @@ namespace OpenTween
         {
             string tabName = null;
             MyCommon.TabUsageType tabUsage;
-            using (InputTabName inputName = new InputTabName())
+            using (var inputName = new InputTabName())
             {
                 inputName.TabName = _statuses.MakeTabName("MyTab");
                 inputName.IsShowUsage = true;
@@ -8034,7 +7987,7 @@ namespace OpenTween
                 ListElement list = null;
                 if (tabUsage == MyCommon.TabUsageType.Lists)
                 {
-                    using (ListAvailable listAvail = new ListAvailable())
+                    using (var listAvail = new ListAvailable())
                     {
                         if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
                         if (listAvail.SelectedList == null) return;
@@ -8060,7 +8013,7 @@ namespace OpenTween
 
                 if (!_statuses.AddTab(tab) || !AddNewTab(tab, startup: false))
                 {
-                    string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
+                    var tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
                     MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                 }
                 else
@@ -8122,8 +8075,8 @@ namespace OpenTween
             {
                 if (StatusText.Focused)
                 {
-                    bool _NewLine = false;
-                    bool _Post = false;
+                    var _NewLine = false;
+                    var _Post = false;
 
                     if (SettingManager.Common.PostCtrlEnter) //Ctrl+Enter投稿時
                     {
@@ -8172,7 +8125,7 @@ namespace OpenTween
 
                     if (_NewLine)
                     {
-                        int pos1 = StatusText.SelectionStart;
+                        var pos1 = StatusText.SelectionStart;
                         if (StatusText.SelectionLength > 0)
                         {
                             StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength);  //選択状態文字列削除
@@ -8226,14 +8179,15 @@ namespace OpenTween
 
             if (screenNameArray.Length != 0)
             {
-                List<string> atids = new List<string>();
+                var atids = new List<string>();
                 foreach (var screenName in screenNameArray)
                 {
                     atids.Add("@" + screenName);
                 }
-                int cnt = AtIdSupl.ItemCount;
+                var cnt = AtIdSupl.ItemCount;
                 AtIdSupl.AddRangeItem(atids.ToArray());
-                if (AtIdSupl.ItemCount != cnt) ModifySettingAtId = true;
+                if (AtIdSupl.ItemCount != cnt)
+                    this.MarkSettingAtIdModified();
             }
         }
 
@@ -8344,7 +8298,7 @@ namespace OpenTween
                 //新規タブを選択→タブ作成
                 if (tabName == null)
                 {
-                    using (InputTabName inputName = new InputTabName())
+                    using (var inputName = new InputTabName())
                     {
                         inputName.TabName = _statuses.MakeTabName("MyTab");
                         inputName.ShowDialog();
@@ -8357,7 +8311,7 @@ namespace OpenTween
                         var tab = new FilterTabModel(tabName);
                         if (!_statuses.AddTab(tab) || !AddNewTab(tab, startup: false))
                         {
-                            string tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText2, tabName);
+                            var tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText2, tabName);
                             MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                             //もう一度タブ名入力
                         }
@@ -8380,7 +8334,7 @@ namespace OpenTween
         {
             {
                 //移動するか?
-                string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine);
+                var _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine);
                 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                     move = false;
                 else
@@ -8389,7 +8343,7 @@ namespace OpenTween
             if (!move)
             {
                 //マークするか?
-                string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine);
+                var _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine);
                 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                     mark = true;
                 else
@@ -8430,7 +8384,7 @@ namespace OpenTween
             var listView = this.CurrentListView;
             if (listView.SelectedIndices.Count == 0) return;
 
-            int idx = listView.SelectedIndices[0];
+            var idx = listView.SelectedIndices[0];
 
             _item = listView.GetItemAt(0, 25);
             if (_item == null)
@@ -8517,7 +8471,7 @@ namespace OpenTween
         {
             if (showWarning)
             {
-                string tmp = string.Format(Properties.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine);
+                var tmp = string.Format(Properties.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine);
                 if (MessageBox.Show(tmp, tabName + " " + Properties.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                 {
                     return;
@@ -8550,9 +8504,9 @@ namespace OpenTween
         private void SetMainWindowTitle()
         {
             //メインウインドウタイトルの書き換え
-            StringBuilder ttl = new StringBuilder(256);
-            int ur = 0;
-            int al = 0;
+            var ttl = new StringBuilder(256);
+            var ur = 0;
+            var al = 0;
             if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None &&
                 SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post &&
                 SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
@@ -8610,15 +8564,15 @@ namespace OpenTween
             //ステータス欄にカウント表示
             //タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
             if (_statuses == null) return "";
-            TabModel tbRep = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
-            TabModel tbDm = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage);
+            var tbRep = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
+            var tbDm = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage);
             if (tbRep == null || tbDm == null) return "";
-            int urat = tbRep.UnreadCount + tbDm.UnreadCount;
-            int ur = 0;
-            int al = 0;
-            int tur = 0;
-            int tal = 0;
-            StringBuilder slbl = new StringBuilder(256);
+            var urat = tbRep.UnreadCount + tbDm.UnreadCount;
+            var ur = 0;
+            var al = 0;
+            var tur = 0;
+            var tal = 0;
+            var slbl = new StringBuilder(256);
             try
             {
                 foreach (var tab in _statuses.Tabs)
@@ -8815,7 +8769,7 @@ namespace OpenTween
             MatchCollection m;
             //ハッシュタグの保存
             m = Regex.Matches(StatusText, Twitter.HASHTAG, RegexOptions.IgnoreCase);
-            string hstr = "";
+            var hstr = "";
             foreach (Match hm in m)
             {
                 if (!hstr.Contains("#" + hm.Result("$3") + " "))
@@ -8835,12 +8789,13 @@ namespace OpenTween
 
             if (SettingManager.Common.UseAtIdSupplement)
             {
-                int bCnt = AtIdSupl.ItemCount;
+                var bCnt = AtIdSupl.ItemCount;
                 foreach (Match mid in m)
                 {
                     AtIdSupl.AddItem(mid.Result("${id}"));
                 }
-                if (bCnt != AtIdSupl.ItemCount) ModifySettingAtId = true;
+                if (bCnt != AtIdSupl.ItemCount)
+                    this.MarkSettingAtIdModified();
             }
 
             // リプライ先ステータスIDの指定がない場合は指定しない
@@ -8898,7 +8853,7 @@ namespace OpenTween
                 if (StatusText.Multiline)
                 {
                     var statusTextHeight = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight);
-                    int dis = SplitContainer2.Height - statusTextHeight - SplitContainer2.SplitterWidth;
+                    var dis = SplitContainer2.Height - statusTextHeight - SplitContainer2.SplitterWidth;
                     if (dis > SplitContainer2.Panel1MinSize && dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth)
                     {
                         SplitContainer2.SplitterDistance = SplitContainer2.Height - statusTextHeight - SplitContainer2.SplitterWidth;
@@ -8942,7 +8897,7 @@ namespace OpenTween
             {
                 SettingManager.Common.PlaySound = false;
             }
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
@@ -8967,7 +8922,7 @@ namespace OpenTween
             }
 
             this._mySpDis = splitterDistance;
-            this.ModifySettingLocal = true;
+            this.MarkSettingLocalModified();
         }
 
         private async Task doRepliedStatusOpen()
@@ -8982,15 +8937,15 @@ namespace OpenTween
                 }
                 if (_statuses.ContainsKey(currentPost.InReplyToStatusId.Value))
                 {
-                    PostClass repPost = _statuses[currentPost.InReplyToStatusId.Value];
+                    var repPost = _statuses[currentPost.InReplyToStatusId.Value];
                     MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname}   ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
                 }
                 else
                 {
-                    foreach (TabModel tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch))
+                    foreach (var tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch))
                     {
                         if (tb == null || !tb.Contains(currentPost.InReplyToStatusId.Value)) break;
-                        PostClass repPost = _statuses[currentPost.InReplyToStatusId.Value];
+                        var repPost = _statuses[currentPost.InReplyToStatusId.Value];
                         MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname}   ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
                         return;
                     }
@@ -9012,7 +8967,7 @@ namespace OpenTween
             {
                 this.StatusText.Multiline = multiline;
                 SettingManager.Local.StatusMultiline = multiline;
-                ModifySettingLocal = true;
+                this.MarkSettingLocalModified();
             }
         }
 
@@ -9023,7 +8978,8 @@ namespace OpenTween
             else
                 this.StatusText.ScrollBars = ScrollBars.None;
 
-            ModifySettingLocal = true;
+            if (!this._initialLayout)
+                this.MarkSettingLocalModified();
         }
 
         private void MultiLineMenuItem_Click(object sender, EventArgs e)
@@ -9043,7 +8999,7 @@ namespace OpenTween
             {
                 SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth;
             }
-            ModifySettingLocal = true;
+            this.MarkSettingLocalModified();
         }
 
         private async Task<bool> UrlConvertAsync(MyCommon.UrlConverter Converter_Type)
@@ -9067,13 +9023,12 @@ namespace OpenTween
             //Appendix A.  Collected ABNF for URI
             //http://www.ietf.org/rfc/rfc3986.txt
 
-            string result = "";
-
             const string nico = @"^https?://[a-z]+\.(nicovideo|niconicommons|nicolive)\.jp/[a-z]+/[a-z0-9]+$";
 
+            string result;
             if (StatusText.SelectionLength > 0)
             {
-                string tmp = StatusText.SelectedText;
+                var tmp = StatusText.SelectedText;
                 // httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
                 if (tmp.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                 {
@@ -9111,7 +9066,7 @@ namespace OpenTween
 
                     if (!string.IsNullOrEmpty(result))
                     {
-                        urlUndo undotmp = new urlUndo();
+                        var undotmp = new urlUndo();
 
                         // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する
                         var origUrlIndex = this.StatusText.Text.IndexOf(tmp, StringComparison.Ordinal);
@@ -9145,10 +9100,12 @@ namespace OpenTween
                 // 正規表現にマッチしたURL文字列をtinyurl化
                 foreach (Match mt in Regex.Matches(StatusText.Text, url, RegexOptions.IgnoreCase))
                 {
-                    if (StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) == -1) continue;
-                    string tmp = mt.Result("${url}");
-                    if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase)) tmp = "http://" + tmp;
-                    urlUndo undotmp = new urlUndo();
+                    if (StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) == -1)
+                        continue;
+                    var tmp = mt.Result("${url}");
+                    if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase))
+                        tmp = "http://" + tmp;
+                    var undotmp = new urlUndo();
 
                     //選んだURLを選択(?)
                     StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
@@ -9223,8 +9180,8 @@ namespace OpenTween
         {
             if (urlUndoBuffer != null)
             {
-                string tmp = StatusText.Text;
-                foreach (urlUndo data in urlUndoBuffer)
+                var tmp = StatusText.Text;
+                foreach (var data in urlUndoBuffer)
                 {
                     tmp = tmp.Replace(data.After, data.Before);
                 }
@@ -9249,8 +9206,9 @@ namespace OpenTween
         {
             if (!await UrlConvertAsync(SettingManager.Common.AutoShortUrlFirst))
             {
-                MyCommon.UrlConverter svc = SettingManager.Common.AutoShortUrlFirst;
-                Random rnd = new Random();
+                var rnd = new Random();
+
+                MyCommon.UrlConverter svc;
                 // 前回使用した短縮URLサービス以外を選択する
                 do
                 {
@@ -9269,7 +9227,7 @@ namespace OpenTween
             this.NotifyFileMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
             this.NewPostPopMenuItem.Checked = this.NotifyFileMenuItem.Checked;
             SettingManager.Common.NewAllPop = NewPostPopMenuItem.Checked;
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void ListLockMenuItem_CheckStateChanged(object sender, EventArgs e)
@@ -9277,13 +9235,13 @@ namespace OpenTween
             ListLockMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
             this.LockListFileMenuItem.Checked = ListLockMenuItem.Checked;
             SettingManager.Common.ListLock = ListLockMenuItem.Checked;
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void MenuStrip1_MenuActivate(object sender, EventArgs e)
         {
             // フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
-            MenuStrip1.Tag = new Object();
+            MenuStrip1.Tag = new object();
             MenuStrip1.Select(); // StatusText がフォーカスを持っている場合 Leave が発生
         }
 
@@ -9308,7 +9266,7 @@ namespace OpenTween
 
         private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e)
         {
-            DetailsListView lst = (DetailsListView)sender;
+            var lst = (DetailsListView)sender;
             if (SettingManager.Local == null) return;
 
             if (_iconCol)
@@ -9318,14 +9276,14 @@ namespace OpenTween
             }
             else
             {
-                int[] darr = new int[lst.Columns.Count];
-                for (int i = 0; i < lst.Columns.Count; i++)
+                var darr = new int[lst.Columns.Count];
+                for (var i = 0; i < lst.Columns.Count; i++)
                 {
                     darr[lst.Columns[i].DisplayIndex] = i;
                 }
                 MyCommon.MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex);
 
-                for (int i = 0; i < lst.Columns.Count; i++)
+                for (var i = 0; i < lst.Columns.Count; i++)
                 {
                     switch (darr[i])
                     {
@@ -9364,27 +9322,27 @@ namespace OpenTween
                 SettingManager.Local.Width7 = lst.Columns[6].Width;
                 SettingManager.Local.Width8 = lst.Columns[7].Width;
             }
-            ModifySettingLocal = true;
+            this.MarkSettingLocalModified();
             _isColumnChanged = true;
         }
 
         private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
         {
-            DetailsListView lst = (DetailsListView)sender;
+            var lst = (DetailsListView)sender;
             if (SettingManager.Local == null) return;
+
+            var modified = false;
             if (_iconCol)
             {
                 if (SettingManager.Local.Width1 != lst.Columns[0].Width)
                 {
                     SettingManager.Local.Width1 = lst.Columns[0].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width3 != lst.Columns[1].Width)
                 {
                     SettingManager.Local.Width3 = lst.Columns[1].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
             }
             else
@@ -9392,52 +9350,49 @@ namespace OpenTween
                 if (SettingManager.Local.Width1 != lst.Columns[0].Width)
                 {
                     SettingManager.Local.Width1 = lst.Columns[0].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width2 != lst.Columns[1].Width)
                 {
                     SettingManager.Local.Width2 = lst.Columns[1].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width3 != lst.Columns[2].Width)
                 {
                     SettingManager.Local.Width3 = lst.Columns[2].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width4 != lst.Columns[3].Width)
                 {
                     SettingManager.Local.Width4 = lst.Columns[3].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width5 != lst.Columns[4].Width)
                 {
                     SettingManager.Local.Width5 = lst.Columns[4].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width6 != lst.Columns[5].Width)
                 {
                     SettingManager.Local.Width6 = lst.Columns[5].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width7 != lst.Columns[6].Width)
                 {
                     SettingManager.Local.Width7 = lst.Columns[6].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
                 if (SettingManager.Local.Width8 != lst.Columns[7].Width)
                 {
                     SettingManager.Local.Width8 = lst.Columns[7].Width;
-                    ModifySettingLocal = true;
-                    _isColumnChanged = true;
+                    modified = true;
                 }
             }
+            if (modified)
+            {
+                this.MarkSettingLocalModified();
+                this._isColumnChanged = true;
+            }
             // 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
             //if (changed)
             //{
@@ -9448,7 +9403,7 @@ namespace OpenTween
         private void SplitContainer2_SplitterMoved(object sender, SplitterEventArgs e)
         {
             if (StatusText.Multiline) _mySpDis2 = StatusText.Height;
-            ModifySettingLocal = true;
+            this.MarkSettingLocalModified();
         }
 
         private void TweenMain_DragDrop(object sender, DragEventArgs e)
@@ -9483,7 +9438,7 @@ namespace OpenTween
             }
             else if (e.Data.GetDataPresent(DataFormats.StringFormat))
             {
-                string data = (string)e.Data.GetData(DataFormats.StringFormat, true);
+                var data = (string)e.Data.GetData(DataFormats.StringFormat, true);
                 if (data != null) StatusText.Text += data;
             }
         }
@@ -9575,8 +9530,7 @@ namespace OpenTween
 
         public bool IsNetworkAvailable()
         {
-            bool nw = true;
-            nw = MyCommon.IsNetworkAvailable();
+            var nw = MyCommon.IsNetworkAvailable();
             _myStatusOnline = nw;
             return nw;
         }
@@ -9647,7 +9601,7 @@ namespace OpenTween
         {
             return Task.Run(() =>
             {
-                string myPath = UriString;
+                var myPath = UriString;
 
                 try
                 {
@@ -9656,9 +9610,9 @@ namespace OpenTween
                     {
                         if (configBrowserPath.StartsWith("\"", StringComparison.Ordinal) && configBrowserPath.Length > 2 && configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal) > -1)
                         {
-                            int sep = configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal);
-                            string browserPath = configBrowserPath.Substring(1, sep - 1);
-                            string arg = "";
+                            var sep = configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal);
+                            var browserPath = configBrowserPath.Substring(1, sep - 1);
+                            var arg = "";
                             if (sep < configBrowserPath.Length - 1)
                             {
                                 arg = configBrowserPath.Substring(sep + 1);
@@ -9702,7 +9656,7 @@ namespace OpenTween
             }
             else
             {
-                for (int i = 0; i < listView.Columns.Count; i++)
+                for (var i = 0; i < listView.Columns.Count; i++)
                 {
                     listView.Columns[i].Text = ColumnText[i];
                 }
@@ -9715,8 +9669,8 @@ namespace OpenTween
         private void SelectListItem(DetailsListView LView, int Index)
         {
             //単一
-            Rectangle bnd = new Rectangle();
-            bool flg = false;
+            var bnd = new Rectangle();
+            var flg = false;
             var item = LView.FocusedItem;
             if (item != null)
             {
@@ -9739,8 +9693,8 @@ namespace OpenTween
         private void SelectListItem(DetailsListView LView , int[] Index, int focusedIndex, int selectionMarkIndex)
         {
             //複数
-            Rectangle bnd = new Rectangle();
-            bool flg = false;
+            var bnd = new Rectangle();
+            var flg = false;
             var item = LView.FocusedItem;
             if (item != null)
             {
@@ -9871,13 +9825,13 @@ namespace OpenTween
 
             _initial = false;
 
-            TimerTimeline.Enabled = true;
+            this.timelineScheduler.Enabled = true;
         }
 
         private async Task doGetFollowersMenu()
         {
             await this.RefreshFollowerIdsAsync();
-            await this.DispSelectedPost(true);
+            this.DispSelectedPost(true);
         }
 
         private async void GetFollowersAllToolStripMenuItem_Click(object sender, EventArgs e)
@@ -9910,7 +9864,7 @@ namespace OpenTween
                 }
                 else if (selectedPosts.Length > 1)
                 {
-                    string QuestionText = Properties.Resources.RetweetQuestion2;
+                    var QuestionText = Properties.Resources.RetweetQuestion2;
                     if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText1;
                     switch (MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
                     {
@@ -9924,7 +9878,7 @@ namespace OpenTween
                 {
                     if (!SettingManager.Common.RetweetNoConfirm)
                     {
-                        string Questiontext = Properties.Resources.RetweetQuestion1;
+                        var Questiontext = Properties.Resources.RetweetQuestion1;
                         if (_DoFavRetweetFlags) Questiontext = Properties.Resources.FavoritesRetweetQuestionText2;
                         if (isConfirm && MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                         {
@@ -10010,12 +9964,12 @@ namespace OpenTween
             return WebUtility.HtmlDecode(statusHtml);
         }
 
-        private async void DumpPostClassToolStripMenuItem_Click(object sender, EventArgs e)
+        private void DumpPostClassToolStripMenuItem_Click(object sender, EventArgs e)
         {
             this.tweetDetailsView.DumpPostClass = this.DumpPostClassToolStripMenuItem.Checked;
 
             if (this.CurrentPost != null)
-                await this.DispSelectedPost(true);
+                this.DispSelectedPost(true);
         }
 
         private void MenuItemHelp_DropDownOpening(object sender, EventArgs e)
@@ -10038,13 +9992,13 @@ namespace OpenTween
         private void IdeographicSpaceToSpaceMenuItem_Click(object sender, EventArgs e)
         {
             SettingManager.Common.WideSpaceConvert = ((ToolStripMenuItem)sender).Checked;
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void FocusLockMenuItem_CheckedChanged(object sender, EventArgs e)
         {
             SettingManager.Common.FocusLockToStatusText = ((ToolStripMenuItem)sender).Checked;
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void PostModeMenuItem_DropDownOpening(object sender, EventArgs e)
@@ -10082,7 +10036,7 @@ namespace OpenTween
         {
             if (string.IsNullOrEmpty(_rclickTabName)) return;
 
-            TabRename(_rclickTabName, out var _);
+            _ = TabRename(_rclickTabName, out _);
         }
 
         private async void BitlyToolStripMenuItem_Click(object sender, EventArgs e)
@@ -10256,7 +10210,7 @@ namespace OpenTween
                     return;
             }
 
-            string result = "";
+            string result;
             if (isFollowing)
             {
                 result = Properties.Resources.GetFriendshipInfo1 + System.Environment.NewLine;
@@ -10279,7 +10233,7 @@ namespace OpenTween
 
         internal async Task ShowFriendship(string[] ids)
         {
-            foreach (string id in ids)
+            foreach (var id in ids)
             {
                 bool isFollowing, isFollowed;
 
@@ -10306,8 +10260,8 @@ namespace OpenTween
                         return;
                 }
 
-                string result = "";
-                string ff = "";
+                var result = "";
+                var ff = "";
 
                 ff = "  ";
                 if (isFollowing)
@@ -10400,7 +10354,7 @@ namespace OpenTween
                     MessageBox.Show("Protected.");
                     return;
                 }
-                string rtdata = post.Text;
+                var rtdata = post.Text;
                 rtdata = CreateRetweetUnofficial(rtdata, this.StatusText.Multiline);
 
                 var selection = (this.StatusText.SelectionStart, this.StatusText.SelectionLength);
@@ -10423,18 +10377,18 @@ namespace OpenTween
         private async void SearchButton_Click(object sender, EventArgs e)
         {
             //公式検索
-            Control pnl = ((Control)sender).Parent;
+            var pnl = ((Control)sender).Parent;
             if (pnl == null) return;
-            string tbName = pnl.Parent.Text;
+            var tbName = pnl.Parent.Text;
             var tb = (PublicSearchTabModel)_statuses.Tabs[tbName];
-            ComboBox cmb = (ComboBox)pnl.Controls["comboSearch"];
-            ComboBox cmbLang = (ComboBox)pnl.Controls["comboLang"];
+            var cmb = (ComboBox)pnl.Controls["comboSearch"];
+            var cmbLang = (ComboBox)pnl.Controls["comboLang"];
             cmb.Text = cmb.Text.Trim();
             // 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする
-            bool Quote = false;
-            StringBuilder buf = new StringBuilder();
-            char[] c = cmb.Text.ToCharArray();
-            for (int cnt = 0; cnt < cmb.Text.Length; cnt++)
+            var Quote = false;
+            var buf = new StringBuilder();
+            var c = cmb.Text.ToCharArray();
+            for (var cnt = 0; cnt < cmb.Text.Length; cnt++)
             {
                 if (cnt > cmb.Text.Length - 4)
                 {
@@ -10472,7 +10426,7 @@ namespace OpenTween
             }
             if (queryChanged)
             {
-                int idx = cmb.Items.IndexOf(tb.SearchWords);
+                var idx = cmb.Items.IndexOf(tb.SearchWords);
                 if (idx > -1) cmb.Items.RemoveAt(idx);
                 cmb.Items.Insert(0, tb.SearchWords);
                 cmb.Text = tb.SearchWords;
@@ -10508,9 +10462,8 @@ namespace OpenTween
             }
             else
             {
-                DetailsListView listView = null;
-
-                TabModel tb = _statuses.RemovedTab.Pop();
+                var tb = _statuses.RemovedTab.Pop();
+                DetailsListView listView;
                 if (tb.TabType == MyCommon.TabUsageType.Related)
                 {
                     var relatedTab = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
@@ -10530,10 +10483,11 @@ namespace OpenTween
                     else
                     {
                         const string TabName = "Related Tweets";
-                        string renamed = TabName;
-                        for (int i = 2; i <= 100; i++)
+                        var renamed = TabName;
+                        for (var i = 2; i <= 100; i++)
                         {
-                            if (!_statuses.ContainsTab(renamed)) break;
+                            if (!_statuses.ContainsTab(renamed))
+                                break;
                             renamed = TabName + i;
                         }
                         tb.TabName = renamed;
@@ -10550,10 +10504,11 @@ namespace OpenTween
                 }
                 else
                 {
-                    string renamed = tb.TabName;
-                    for (int i = 1; i < int.MaxValue; i++)
+                    var renamed = tb.TabName;
+                    for (var i = 1; i < int.MaxValue; i++)
                     {
-                        if (!_statuses.ContainsTab(renamed)) break;
+                        if (!_statuses.ContainsTab(renamed))
+                            break;
                         renamed = tb.TabName + "(" + i + ")";
                     }
                     tb.TabName = renamed;
@@ -10606,7 +10561,7 @@ namespace OpenTween
 
         private void SearchControls_Enter(object sender, EventArgs e)
         {
-            Control pnl = (Control)sender;
+            var pnl = (Control)sender;
             foreach (Control ctl in pnl.Controls)
             {
                 ctl.TabStop = true;
@@ -10615,7 +10570,7 @@ namespace OpenTween
 
         private void SearchControls_Leave(object sender, EventArgs e)
         {
-            Control pnl = (Control)sender;
+            var pnl = (Control)sender;
             foreach (Control ctl in pnl.Controls)
             {
                 ctl.TabStop = false;
@@ -10634,7 +10589,7 @@ namespace OpenTween
 
         private void HashManageMenuItem_Click(object sender, EventArgs e)
         {
-            DialogResult rslt = DialogResult.Cancel;
+            DialogResult rslt;
             try
             {
                 rslt = HashMgr.ShowDialog();
@@ -10671,7 +10626,7 @@ namespace OpenTween
             //    StatusText.SelectionStart = sidx;
             //    StatusText.Focus();
             //}
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
             this.StatusText_TextChanged(null, null);
         }
 
@@ -10690,7 +10645,7 @@ namespace OpenTween
                 HashToggleMenuItem.Checked = false;
                 HashTogglePullDownMenuItem.Checked = false;
             }
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
             this.StatusText_TextChanged(null, null);
         }
 
@@ -10704,7 +10659,7 @@ namespace OpenTween
             HashTogglePullDownMenuItem.Checked = true;
             HashToggleMenuItem.Checked = true;
             //使用ハッシュタグとして設定
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void MenuItemOperate_DropDownOpening(object sender, EventArgs e)
@@ -10838,7 +10793,7 @@ namespace OpenTween
             }
 
             this._mySpDis3 = splitterDistance;
-            this.ModifySettingLocal = true;
+            this.MarkSettingLocalModified();
         }
 
         private void MenuItemEdit_DropDownOpening(object sender, EventArgs e)
@@ -10987,7 +10942,7 @@ namespace OpenTween
             MessageBox.Show(status.RetweetCount + Properties.Resources.RtCountText1);
         }
 
-        private HookGlobalHotkey _hookGlobalHotkey;
+        private readonly HookGlobalHotkey _hookGlobalHotkey;
         public TweenMain()
         {
             _hookGlobalHotkey = new HookGlobalHotkey(this);
@@ -11005,7 +10960,6 @@ namespace OpenTween
 
             this.tweetDetailsView.Owner = this;
 
-            this.TimerTimeline.Elapsed += this.TimerTimeline_Elapsed;
             this._hookGlobalHotkey.HotkeyPressed += _hookGlobalHotkey_HotkeyPressed;
             this.gh.NotifyClicked += GrowlHelper_Callback;
 
@@ -11092,9 +11046,7 @@ namespace OpenTween
         {
             if (ImageSelector.Visible)
             {
-                ModifySettingCommon = true;
-                SaveConfigsAll(true);
-
+                this.MarkSettingCommonModified();
                 this.StatusText_TextChanged(null, null);
             }
         }
@@ -11141,15 +11093,15 @@ namespace OpenTween
 
         private void ListManageToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            using (ListManage form = new ListManage(tw))
+            using (var form = new ListManage(tw))
             {
                 form.ShowDialog(this);
             }
         }
 
-        public bool ModifySettingCommon { get; set; }
-        public bool ModifySettingLocal { get; set; }
-        public bool ModifySettingAtId { get; set; }
+        private bool ModifySettingCommon { get; set; }
+        private bool ModifySettingLocal { get; set; }
+        private bool ModifySettingAtId { get; set; }
 
         private void MenuItemCommand_DropDownOpening(object sender, EventArgs e)
         {
@@ -11272,7 +11224,7 @@ namespace OpenTween
 
         private void CacheInfoMenuItem_Click(object sender, EventArgs e)
         {
-            StringBuilder buf = new StringBuilder();
+            var buf = new StringBuilder();
             //buf.AppendFormat("キャッシュメモリ容量         : {0}bytes({1}MB)" + Environment.NewLine, IconCache.CacheMemoryLimit, ((ImageDictionary)IconCache).CacheMemoryLimit / 1048576);
             //buf.AppendFormat("物理メモリ使用割合           : {0}%" + Environment.NewLine, IconCache.PhysicalMemoryLimit);
             buf.AppendFormat("キャッシュエントリ保持数     : {0}" + Environment.NewLine, IconCache.CacheCount);
@@ -11280,9 +11232,6 @@ namespace OpenTween
             MessageBox.Show(buf.ToString(), "アイコンキャッシュ使用状況");
         }
 
-        private void tw_UserIdChanged()
-            => this.ModifySettingCommon = true;
-
 #region "Userstream"
         private async void tw_PostDeleted(object sender, PostDeletedEventArgs e)
         {
@@ -11290,7 +11239,7 @@ namespace OpenTween
             {
                 if (InvokeRequired && !IsDisposed)
                 {
-                    await this.InvokeAsync(async () =>
+                    await this.InvokeAsync(() =>
                     {
                         this._statuses.RemovePostFromAllTabs(e.StatusId, setIsDeleted: true);
                         if (this.CurrentTab.Contains(e.StatusId))
@@ -11299,7 +11248,7 @@ namespace OpenTween
                             this.CurrentListView.Update();
                             var post = this.CurrentPost;
                             if (post != null && post.StatusId == e.StatusId)
-                                await this.DispSelectedPost(true);
+                                this.DispSelectedPost(true);
                         }
                     });
                     return;
@@ -11439,7 +11388,7 @@ namespace OpenTween
                 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
                 //if (SettingDialog.DispUsername) NotifyIcon1.BalloonTipTitle = tw.Username + " - "; else NotifyIcon1.BalloonTipTitle = "";
                 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [" + ev.Event.ToUpper() + "] by " + ((string)(!string.IsNullOrEmpty(ev.Username) ? ev.Username : ""), string);
-                StringBuilder title = new StringBuilder();
+                var title = new StringBuilder();
                 if (SettingManager.Common.DispUsername)
                 {
                     title.Append(tw.Username);
@@ -11488,19 +11437,19 @@ namespace OpenTween
             }
 
             //サウンド再生
-            string snd = SettingManager.Common.EventSoundFile;
+            var snd = SettingManager.Common.EventSoundFile;
             if (!_initial && SettingManager.Common.PlaySound && !string.IsNullOrEmpty(snd))
             {
                 if ((ev.Eventtype & SettingManager.Common.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev))
                 {
                     try
                     {
-                        string dir = Application.StartupPath;
+                        var dir = Application.StartupPath;
                         if (Directory.Exists(Path.Combine(dir, "Sounds")))
                         {
                             dir = Path.Combine(dir, "Sounds");
                         }
-                        using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, snd)))
+                        using (var player = new SoundPlayer(Path.Combine(dir, snd)))
                         {
                             player.Play();
                         }
@@ -11536,7 +11485,7 @@ namespace OpenTween
         {
             if (TrackToolStripMenuItem.Checked)
             {
-                using (InputTabName inputForm = new InputTabName())
+                using (var inputForm = new InputTabName())
                 {
                     inputForm.TabName = inputTrack;
                     inputForm.FormTitle = "Input track word";
@@ -11551,7 +11500,7 @@ namespace OpenTween
                 if (!inputTrack.Equals(tw.TrackWord))
                 {
                     tw.TrackWord = inputTrack;
-                    this.ModifySettingCommon = true;
+                    this.MarkSettingCommonModified();
                     TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(inputTrack);
                     tw.ReconnectUserStream();
                 }
@@ -11561,13 +11510,13 @@ namespace OpenTween
                 tw.TrackWord = "";
                 tw.ReconnectUserStream();
             }
-            this.ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void AllrepliesToolStripMenuItem_Click(object sender, EventArgs e)
         {
             tw.AllAtReply = AllrepliesToolStripMenuItem.Checked;
-            this.ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
             tw.ReconnectUserStream();
         }
 
@@ -11633,7 +11582,7 @@ namespace OpenTween
         {
             var id = this.CurrentPost?.ScreenName ?? "";
 
-            using (InputTabName inputName = new InputTabName())
+            using (var inputName = new InputTabName())
             {
                 inputName.FormTitle = caption;
                 inputName.FormDescription = Properties.Resources.FRMessage1;
@@ -11653,7 +11602,7 @@ namespace OpenTween
 
         private async void UserTimelineToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            string id = GetUserIdFromCurPostOrInput("Show UserTimeline");
+            var id = GetUserIdFromCurPostOrInput("Show UserTimeline");
             if (!string.IsNullOrEmpty(id))
             {
                 await this.AddNewTabForUserTimeline(id);
@@ -11662,10 +11611,11 @@ namespace OpenTween
 
         private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
         {
-            if (e.Mode == Microsoft.Win32.PowerModes.Resume) osResumed = true;
+            if (e.Mode == Microsoft.Win32.PowerModes.Resume)
+                this.timelineScheduler.SystemResumed();
         }
 
-        private async void SystemEvents_TimeChanged(object sender, EventArgs e)
+        private void SystemEvents_TimeChanged(object sender, EventArgs e)
         {
             var prevTimeOffset = TimeZoneInfo.Local.BaseUtcOffset;
 
@@ -11679,7 +11629,7 @@ namespace OpenTween
                 this.PurgeListViewItemCache();
                 this.CurrentListView.Refresh();
 
-                await this.DispSelectedPost(forceupdate: true);
+                this.DispSelectedPost(forceupdate: true);
             }
         }
 
@@ -11693,7 +11643,7 @@ namespace OpenTween
             {
                 tw.StopUserStream();
             }
-            TimerTimeline.Enabled = isEnable;
+            this.timelineScheduler.Enabled = isEnable;
         }
 
         private void StopRefreshAllMenuItem_CheckedChanged(object sender, EventArgs e)
@@ -11708,7 +11658,7 @@ namespace OpenTween
                     var post = this.CurrentPost;
                     if (post != null)
                     {
-                        string xUrl = SettingManager.Common.UserAppointUrl;
+                        var xUrl = SettingManager.Common.UserAppointUrl;
                         xUrl = xUrl.Replace("{ID}", post.ScreenName);
 
                         var statusId = post.RetweetedId ?? post.StatusId;
@@ -11828,8 +11778,7 @@ namespace OpenTween
             }
 
             this.CurrentListView.Refresh();
-
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void LockListSortToolStripMenuItem_Click(object sender, EventArgs e)
@@ -11838,8 +11787,7 @@ namespace OpenTween
             if (SettingManager.Common.SortOrderLock == state) return;
 
             SettingManager.Common.SortOrderLock = state;
-
-            ModifySettingCommon = true;
+            this.MarkSettingCommonModified();
         }
 
         private void tweetDetailsView_StatusChanged(object sender, TweetDetailsViewStatusChengedEventArgs e)