private int refreshTimerEnabled = 0;
public TimeSpan Interval { get; }
+ public TimeSpan MaxWait { get; }
- public ThrottlingTimer(Func<Task> timerCallback, TimeSpan interval)
+ public ThrottlingTimer(Func<Task> timerCallback, TimeSpan interval, TimeSpan maxWait)
{
this.timerCallback = timerCallback;
this.Interval = interval;
+ this.MaxWait = maxWait;
this.throttlingTimer = new Timer(this.Execute);
}
}
else
{
- this.lastInvoked = DateTimeUtc.Now;
- await this.timerCallback().ConfigureAwait(false);
+ var now = DateTimeUtc.Now;
+ if ((now - this.lastCalled) >= this.Interval || (now - this.lastInvoked) >= this.MaxWait)
+ {
+ this.lastInvoked = now;
+ await this.timerCallback().ConfigureAwait(false);
+ }
// dueTime は Execute が呼ばれる度に再設定する (period は使用しない)
// これにより timerCallback の実行に Interval 以上の時間が掛かっても重複して実行されることはなくなる
public void Dispose()
=> this.throttlingTimer.Dispose();
- // lodash.js の _.throttle 的な処理をしたかったメソッド
+ // lodash.js の _.throttle, _.debounce 的な処理をしたかったメソッド群
public static ThrottlingTimer Throttle(Func<Task> callback, TimeSpan wait)
- => new ThrottlingTimer(callback, wait);
+ => new ThrottlingTimer(callback, wait, maxWait: wait);
+
+ public static ThrottlingTimer Debounce(Func<Task> callback, TimeSpan wait)
+ => new ThrottlingTimer(callback, wait, maxWait: TimeSpan.MaxValue);
}
}
private bool osResumed = false;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
- private bool _colorize = false;
private System.Timers.Timer TimerTimeline = new System.Timers.Timer();
private ThrottlingTimer RefreshThrottlingTimer;
+ private ThrottlingTimer selectionDebouncer;
private string recommendedStatusFooter;
private bool urlMultibyteSplit = false;
var streamingRefreshInterval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod);
this.RefreshThrottlingTimer = ThrottlingTimer.Throttle(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval);
+ this.selectionDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100));
TimerTimeline.AutoReset = true;
TimerTimeline.SynchronizingObject = this;
this._statuses.SetReadAllTab(post.StatusId, read: true);
//キャッシュの書き換え
ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色)
-
ColorizeList();
- _colorize = true;
+
+ this.selectionDebouncer.Call();
}
private void ChangeCacheStyleRead(bool Read, int Index)
}
}
- private async Task Colorize()
+ private async Task UpdateSelectedPost()
{
- _colorize = false;
- await this.DispSelectedPost();
//件数関連の場合、タイトル即時書き換え
if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None &&
SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post &&
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)
}
}
}
- if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
+ else
+ {
+ this.ListTab.Refresh();
+ }
+
+ await this.DispSelectedPost();
}
public string createDetailHtml(string orgdata)
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)
private static bool blink = false;
private static bool idle = false;
- private async Task RefreshTasktrayIcon()
+ private void RefreshTasktrayIcon()
{
- if (_colorize)
- await this.Colorize();
-
if (!TimerRefreshIcon.Enabled) return;
//Static usCheckCnt As int = 0
}
}
- 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)
{