打破c#中包含async await的while循环
本文关键字:while 循环 await async 包含 打破 | 更新日期: 2023-09-27 18:02:03
我有以下代码。但我有问题打破这个循环立即。当我把if/break语句放在循环的底部时,它会在循环结束时中断循环。所以我把if/break语句在每个延迟语句之后。虽然它工作(不是工作得"很好"),但我搜索另一个修复来打破这个循环立即在这个循环
的任何地方private bool btns = false;
private void button19_Click(object sender, EventArgs e)
{
btns = true;
activatepuckbuttons();
btn_status = true;
label25.Visible = false;
pictureBox1.Visible = false;
}
private async void autoshot()
{
while (1>0)
{
myport.Write("A1");
label24.Text = "A";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("A0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("B1");
label24.Text = "B";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("B0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("C1");
label24.Text = "C";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("C0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("D1");
label24.Text = "D";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("D0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("E1");
label24.Text = "E";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("E0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("F1");
label24.Text = "F";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("F0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("G1");
label24.Text = "G";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("G0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("H1");
label24.Text = "H";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("H0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("I1");
label24.Text = "I";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("I0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("J1");
label24.Text = "J";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("J0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("K1");
label24.Text = "K";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("K0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("L1");
label24.Text = "L";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("L0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("M1");
label24.Text = "M";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("M0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("N1");
label24.Text = "N";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("N0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("O1");
label24.Text = "O";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("O0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
// ---
myport.Write("P1");
label24.Text = "P";
await Task.Delay(700);
if (btns == true)
{
break;
}
myport.Write("P0");
label24.Text = "";
await Task.Delay(2300);
if (btns == true)
{
break;
}
}
}
您需要做的是用CancellationToken
替换btns
,这将让您尽早停止Task.Delay
,但是当它停止时将抛出异常,因此我们需要稍微修改代码以捕获该异常。
private CancellationTokenSource tokenSource = new CancellationTokenSource();
private void button19_Click(object sender, EventArgs e)
{
//Signala the token source to cancel;
tokenSource.Cancel();
//Make a new token source, autoshot will still be listening to the old source because we passed in the token as an argument.
tokenSource = new CancellationTokenSource();
activatepuckbuttons();
btn_status = true;
label25.Visible = false;
pictureBox1.Visible = false;
}
//We don't make this async void because we don't use await.
private void StartAutoShotButton_Click(object sender, EventArgs e)
{
//We do not await this because we are using it in a fire-and-forget fashion.
autoshot(tokenSource.Token);
}
//It is a bad habit to do `async void` when not using a event. Just have it return a task but not wait on it.
private async Task autoshot(CancellationToken token)
{
try
{
while (true)
{
myport.Write("A1");
label24.Text = "A";
await Task.Delay(700, token);
myport.Write("A0");
label24.Text = "";
await Task.Delay(2300, token);
// ---
myport.Write("B1");
label24.Text = "B";
await Task.Delay(700, token);
myport.Write("B0");
label24.Text = "";
await Task.Delay(2300, token);
}
//...
}
catch(OperationCanceledException ex)
{
if(ex.CancellationToken 1= token)
{
//Something other than our token caused a cancel, we should let the error bubble up.
throw;
}
}
}