至少有一個這樣的問題,答案是“只需使用秒表”。我很樂意這樣做,除了Stopwatch鎖定 UI,所以我不得不使用Timer. 但我不知道如何獲得經過的時間。我必須在 UI 上顯示它。
問題:等待 X 秒并執行某些操作,并顯示經過的時間。
計時器,簡單但不能過時:
Timer timer = new Timer
{
Interval = 8000 //8 seconds
};
timer.Enabled = true;
timer.Elapsed = DoSomething;
秒表,不是真正令人愉快的代碼,它阻止了 UI,但可以很容易地獲得經過的時間Elapsed:
Stopwatch st = new Stopwatch();
st.Start();
do
{
//wait 8 seconds
} while (st.ElapsedMilliseconds < 8000);
DoSomething2();
基本上這兩件事都不會做我真正想要的。而且我確信有一種方法可以實作我所需要的。
uj5u.com熱心網友回復:
等待 X 秒并做某事,并顯示經過的時間
這是兩個不同的目標。定時器適合做第一個,但也可以使用類似await Task.Delay(...)內部使用定時器的方法。
對于第二個目標,您可以假設計時器確實經過了正確的時間,也可以使用秒表自己測量實際時間。但是時間的測量與等待部分是分開的。例如
var waitTime = TimeSpan.FromSeconds(8)
var startTime = DateTime.Now;
var stopwatch = Stopwatch.StartNew();
await Task.Delay(waitTime);
// Use waitTime for a rough estimation of the passed time
// (DateTime.Now - startTime ) for a measurement accurate to the system clock, often about 16ms
// stopwatch.Elapsed for an accurate measurement to the tick-frequency (usually much better than a microsecond)
uj5u.com熱心網友回復:
如你所說:
- 跑。
- 等待 8 秒。
- 做點別的。
- 顯示經過的時間。
可以通過下一個示例來實作:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private readonly Stopwatch sw = new Stopwatch();
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
Task.Run(() => DoSomething());
}
private async Task DoSomething()
{
sw.Start();
await Task.Delay(8000);
DoSomething2();
sw.Stop();
Dispatcher.Invoke(() =>
lblResult.Content = "Job complete. Elapsed: " sw.Elapsed.ToString());
sw.Reset();
}
private void DoSomething2()
{
// Do it, c'mon
}
}
當單擊“開始”按鈕時 - 您在新執行緒中運行作業,因此不會因掛起或凍結而影響您的視窗。你會得到這樣的輸出:

如果您需要在某項運行時查看時間測量的進度,您可以在啟動Stopwatch( sw.Start())后立即添加此示例塊:
//...
sw.Start();
Task.Run(() =>
{
Dispatcher.Invoke(() =>
logTextBlock.Text = "Something started.\n\n");
while (sw.IsRunning)
{
Dispatcher.Invoke(() =>
logTextBlock.Text = "Something running. Elapsed: " sw.Elapsed.ToString() "\n");
Task.Delay(1000).Wait();
}
Dispatcher.Invoke(() =>
logTextBlock.Text = "\nSomething complete. Elapsed: " sw.Elapsed.ToString() "\n");
sw.Reset(); // Put reset from outer scope inside here
});
await Task.Delay(8000);
// ...
請注意,在這種情況下,sw.Reset()應將其放入該塊中,而不是像第一個示例中那樣放在該塊之外。
你可以得到這樣的輸出:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/315352.html
下一篇:使用Helix工具的WPF,在嘗試更新ModelVisual3D視圖時,PropertyChangedEventHandler始終為null
