我知道对于异步操作而言,可以跟踪其进度,但是稍后我会尝试。现在,我有一个简单的窗口表单,它带有一个按钮(或一对按钮-数量无关紧要)。这些按钮调用异步操作
public async void Button1_Click(...)
{
await Button1_OperationAsync(...);
}
如果我不按该按钮,则什么也没有做,但是如果我按下该按钮,Button1_OperationAsync
一旦启动(并等待)。 (我不确定是否将其称为“线程”)。
但是,如果我按下两次按钮会怎样?那么,在第一个异步操作完成之前,将再次调用Button1_OperationAsync
。 (或者,如果按下了另一个类似的按钮,则会调用Button2_OperationAsync
)
也许第二个异步操作也将在第一个异步操作之前完成。
我想要的是一种简单的方法来知道是否正在进行任何操作。因此,我认为要有一个变量,在调用操作时将其递增,在操作完成时将其递减。像
int numberOfOps=0;
public async void Button1_Click(...)
{ numberOfOps++;
textBox1.Text="Started!";
await Button1_OpeationAsync(...);
numberOfOps--;
if(numberOfOps<=0)
{
textBox1.Text="Done!";
}
}
请注意,此代码也将出现在另一个按钮(Button2)中。或许多其他按钮。
我知道可能会涉及同步问题。因此,我很乐意为正确执行操作提供建议
答案 0 :(得分:0)
使用async
/ await
时,除了UI线程外,您没有使用其他任何线程来编写UI代码。在Button1_OpeationAsync
方法中调用的代码可能使用单独的线程,但是调用的代码将保留在UI线程上。
尝试使用以下代码进行游戏:
private int numberOfOps = 0;
private async void button1_Click(object sender, EventArgs e)
{
textBox1.Text = $"Started! {++numberOfOps}";
await Task.Delay(TimeSpan.FromSeconds(5.0));
textBox1.Text = $"Started! {--numberOfOps}";
if (numberOfOps == 0)
{
textBox1.Text = "Done!";
}
}
效果很好。您可以在多个按钮之间使用numberOfOps
变量。
如果您想简化代码的重用,请尝试以下方式:
int numberOfOps = 0;
private async Task RunOp(Func<Task> op)
{
textBox1.Text = $"Started! {++numberOfOps}";
await op();
textBox1.Text = $"Started! {--numberOfOps}";
if (numberOfOps == 0)
{
textBox1.Text = "Done!";
}
}
private async void button1_Click(object sender, EventArgs e)
{
await this.RunOp(() => Button1_OpeationAsync(...));
}
private async void button2_Click(object sender, EventArgs e)
{
await this.RunOp(() => Button2_OpeationAsync(...));
}
答案 1 :(得分:-1)
在类级别具有一个任务数组和一个任务对象:
private List<Task> tasks = new List<Task>();
private Task task = null;
在每个点击处理程序中,请执行以下操作:
var operationTask = SomeOperationAsync(...);
tasks.Add(operationTask);
task = Task.WhenAll(tasks);
if (task.IsCompleted)
{
// no operation is going on
tasks.Clear();
// do what ever you want to do further
}
else
{
//some operation is going on
}