【发布时间】:2020-01-07 19:30:26
【问题描述】:
我有一个包含两个DataGridView 控件的表单,每个控件都有一个刷新按钮。控件从两种方法(task1 和 task2)获取数据。还有一个通用刷新按钮可以重新填充这两个控件。
填充控件的两种方法不能同时运行并且很耗时(每个大约 1 分钟),因此我希望它们在后台运行以保持表单处于活动状态。
当我按下每个刷新按钮时,我想取消当前正在进行的任何活动任务并重新开始。
另外,我已经实现了一个进度条来填充每个方法。
到目前为止,我已经写了这段代码:
- 注意:编写任务仅用于测试使用
async-await和Task.Run的逻辑
public bool pending = false; // I have used a public boolean to determine if the tasks are in progress.
private async void Button1_Click(object sender, EventArgs e)
{
var progress = new Progress<int>(value => { toolStripProgressBar1.Value = value; });
string test2 = "";
string test1 = "";
CancellationTokenSource source = new CancellationTokenSource();
if (pending)
{source.Cancel();}
pending = true;
await Task.Run(() =>
{
test1 = task1(progress, source.Token);
});
toolStripProgressBar1.Value = 0;
await Task.Run(() =>
{
test2 = task2(progress, source.Token);
});
pending = false;
toolStripProgressBar1.Value = 0;
}
private string task1(IProgress<int> progress, CancellationToken token)
{
if (token.IsCancellationRequested)
{
return "cancelled";
}
for (int i = 0; i != 100; ++i)
{
if (progress != null)
progress.Report(i);
Thread.Sleep(100);
Console.WriteLine(i.ToString() + ";");
if (token.IsCancellationRequested)
{
return "cancelled";
}
}
return "task1";
}
private string task2(IProgress<int> progress, CancellationToken token)
{
if (token.IsCancellationRequested)
{
return "cancelled";
}
for (int i = 0; i != 100; ++i)
{
if (progress != null)
progress.Report(i);
Thread.Sleep(100);
Console.WriteLine(i.ToString() + ";");
if (token.IsCancellationRequested)
{
return "cancelled";
}
}
return "task2";
}
- 注意:Button_1 控件是一个接一个地运行这两种方法的通用刷新按钮。 Button_2 和 Button_3 Click 事件代码类似于 Button_1 Click 事件,但它只运行一个任务,而不是同时运行两个任务。为了保持代码干净,我没有把它们放在这里。
使用此代码,我得到以下行为。
第一次单击 Button_1 - 代码运行正常,进度条运行正常且完全。
在进度条完成之前第二次单击 Button_1(bool 挂起为真) - 进度条重新启动但立即恢复到初始进度并且初始计数仍在运行,不会被
if (token.IsCancellationRequested)取消在进度条完成之前第三次单击 Button_1 - 进度条开始闪烁,初始计数仍在运行,另一个计数开始。
我知道代码不完整,因为我没有找到在方法被取消后重新启动它们的方法。
分析到目前为止我是如何编写代码的,我不明白进度条的行为。另外,我不明白为什么当我第二次单击按钮时第一个计数仍在运行。 在再次调用它们之前取消任何正在运行的任务的最佳方法是什么?
【问题讨论】:
标签: c# async-await task