在C#4.5的Windows窗体应用程序编程中,使用Task和async关键字创建异步操作“精确地测量长时间运行任务的持续时间并实时显示已执行时间”的完整示例代码。
时间: 2024-09-14 16:02:57 浏览: 41
C# 窗体程序Winform 委托和多线程练习-摇奖器案例源码
5星 · 资源好评率100%
在C# 4.5及以上版本的Windows窗体应用程序中,你可以使用`Task`、`async`以及`DateTime`来精确测量长时间运行任务的持续时间和实时更新进度。以下是一个简单的示例,展示了如何在一个`BackgroundWorker`的基础上使用`async`和`await`来更新UI:
首先,在Windows Forms项目中添加一个计时器和一些文本框用于显示执行时间和暂停/继续按钮:
```xml
<Label Text="执行时间:" AutoSize=False/>
<TextBox Name="timeElapsedTextBox" />
<Button Text="开始" Click="buttonStart_Click" />
<Button Text="暂停" Enabled=False Click="buttonPause_Click" />
<Button Text="继续" Enabled=False Click="buttonContinue_Click" />
<Timer Interval="1000" Tick="timer_Tick" />
```
然后编写C#代码:
```csharp
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
public partial class Form1 : Form
{
private BackgroundWorker backgroundWorker;
private Timer timer;
private DateTime startTime;
private bool isPaused;
public Form1()
{
InitializeComponent();
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
timer = new Timer();
timer.Tick += Timer_Tick;
}
private async void buttonStart_Click(object sender, EventArgs e)
{
isPaused = false;
startTime = DateTime.Now;
timer.Start();
backgroundWorker.RunWorkerAsync();
}
private void buttonPause_Click(object sender, EventArgs e)
{
isPaused = !isPaused;
}
private async void buttonContinue_Click(object sender, EventArgs e)
{
if (isPaused)
{
isPaused = false;
await backgroundWorker;
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 1000000; i++)
{
if (!isPaused)
e.ReportProgress(i);
}
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
timeElapsedTextBox.Text = $"{DateTime.Now - startTime.ToString("HH:mm:ss.FFF")} 已执行: {e.ProgressPercentage}%";
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timer.Stop();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (!isPaused && backgroundWorker.IsBusy)
{
TimeSpan elapsedTime = DateTime.Now - startTime;
double progress = Math.Min((double)elapsedTime.TotalMilliseconds / (double)(backgroundWorker.WorkerTotalLoops * 10), 100);
backgroundWorker.ReportProgress(Convert.ToInt32(progress));
}
}
}
```
这个示例中,当用户点击"开始"按钮时,一个计数器开始运行,每秒报告一次进度。如果用户点击"暂停",则计时器暂停,直到再次点击"继续"。注意`ProgressChanged`事件会在工作线程上调用,所以我们需要通过`await`传递进度给UI线程。
阅读全文