【发布时间】:2019-10-31 14:24:12
【问题描述】:
下面提到的 UpdateMethod 可以从各种用户操作中调用,例如按钮 UpdateSW1、UpdateSW2、UpdateSW3。
如果用户点击按钮 UpdateSW1,它会暂停任务 10 秒,这里的 waitTime 是 2。现在,当此单击完成时,用户也可以单击 UpdateSW2,当发生这种情况时,我想取消由于第一次单击 (UpdateSW1) 而导致的任务正在进行的延迟或其他操作,并开始 UpdateSW2 的操作。
private void UpdateMethod(int waitTime, int actionNo)
{
Task.Run(async () =>
{
while (waitTime != 0)
{
waitTime--;
await Task.Delay(5000);
}
// DO other stuff ...
if (actionNO == 1)
{
//ops for UpdateSW1
}
else
{
//ops for UpdateSW2.
}
});
}
更新1:
经过一些试验,我想出了以下代码,现在这在某种程度上可以正常工作,但仍需要改进。如果用户依次单击按钮 UpdateSW1 和 UpdateSW2 ,然后单击取消按钮,它会取消其中一个任务(由于 UpdateSW1 click 正在运行)但不取消另一个任务(其中一个由于单击 updteSW2 正在运行)我希望取消这两个任务。如何做到这一点。
修改方法:
private CancellationTokenSource cts; // declared as class variable.
private void UpdateMethod(int waitTime, int actionNo)
{
cts = new CancellationTokenSource();
CancellationToken token1 = cts.Token;
try
{
Task.Run(async () =>
{
while (waitTime != 0)
{
waitTime--;
await Task.Run(() => Task.Delay(5000, token1), token1);
token1.ThrowIfCancellationRequested();
}
// DO other stuff ...
if (actionNO == 1)
{
//ops for UpdateSW1
}
else
{
//ops for UpdateSW2.
}
}, token1);
}
catch (OperationCanceledException e)
{
// update DB log
}
}
【问题讨论】:
-
取消意味着取消,而不是暂停或取消暂停。带信号的取消令牌意味着整个
UpdateMethod应该尽快停止。如果您想在继续之前等待某些用户输入或其他事件,请使用由 click 事件处理程序发出信号的 TaskCompletionSource。如果你想把它和超时结合起来,你可以使用await Task.WhenAny(taskFromSource,Task.Delay(10000)); -
对不起,我想我应该更清楚地表达我的问题。我的基本意思是,一旦调用 updateMethod,它基本上会在任何操作开始之前等待一段时间(取决于参数 waitTime)。现在在这段等待或等待后的操作执行期间,用户可以点击UpdateSW2,如果发生这种情况,我希望取消当前正在进行的任务并重新开始。我可以研究关于信号取消令牌的任何样本或文章吗?不幸的是,我对此进行了谷歌搜索,无法理解或找到一个简单的示例。
-
我认为你的 catch 块在方法之外不正确。