使用取消令牌取消多个任务
Use a cancellation Token to cancel multiple Tasks
我想知道如何取消任务。已经读过一些这样的文章:https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads?redirectedfrom=MSDN
但是我已经完成了任务,想知道如何让它们可取消。
要么一次全部完成,如果不可能,则应取消一个任务,然后他应取消下一个任务,直到全部完成。
EDIT CancellationToken 的使用是否正确?
任务按照我的意愿继续 运行,但是当我按下取消按钮时,出现错误。如果我启动我发布的版本,应用程序就会关闭:*
enter image description here
void btnPause_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try
{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => START(token));
await Task.WhenAny(new[] { t1 });
}
catch (OperationCanceledException)
{
// Handle canceled
}
catch (Exception)
{
// Handle other exceptions
}
}
///////////////////////////////////////////
async void START(CancellationToken token)
{
for (int i = 0; i < 1; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(2000);
var t2 = Task.Run(() => START2(token));
await Task.WhenAny(new[] { t2});
}
///////////////////////////////////////////////
async void START2(CancellationToken token)
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(7000);
var t3 = Task.Run(() => MOVE(token));
await Task.WhenAny(new[] {t3});
}
//////////////////////////////////////////
async void MOVE(CancellationToken token)
{
for (int i = 0; i < 3; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
var t4 = Task.Run(() => MOVE2(token));
await Task.WhenAny(new[] {t4 });
}
在稍微简化的示例中使用 CancellationTokenSource:
CancellationTokenSource cts = new CancellationTokenSource();
async void Cancel_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => Start(token));
var t2 = Task.Run(() => Start(token));
await Task.WhenAny(new []{t1, t2});
}
catch(OperationCancelledException){
// Handle canceled
}
catch(Exception){
// Handle other exceptions
}
}
void Start(CancellationToken token)
{
for (int i = 0; i < 100; i++)
{
token.ThrowIfCancellationRequested();
// Do work
Thread.Sleep(100);
}
}
单击该按钮时,它将首先创建一个新的 cancellationTokenSource,然后在后台线程上启动两个任务,这两个任务都使用来自新创建的令牌源的令牌。当按下 cancelButton 时,令牌将设置为 canceled-state,下次每个后台线程调用 ThrowIfCancellationRequested 时,它们将抛出异常。这会将任务放入 canceled-state,等待这将抛出需要捕获的 operationCancelledException。请注意,当等待多个任务时,您可能会得到一个 aggregateException,它包装了多个异常并需要解包。
我想知道如何取消任务。已经读过一些这样的文章:https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads?redirectedfrom=MSDN
但是我已经完成了任务,想知道如何让它们可取消。
要么一次全部完成,如果不可能,则应取消一个任务,然后他应取消下一个任务,直到全部完成。
EDIT CancellationToken 的使用是否正确? 任务按照我的意愿继续 运行,但是当我按下取消按钮时,出现错误。如果我启动我发布的版本,应用程序就会关闭:* enter image description here
void btnPause_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try
{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => START(token));
await Task.WhenAny(new[] { t1 });
}
catch (OperationCanceledException)
{
// Handle canceled
}
catch (Exception)
{
// Handle other exceptions
}
}
///////////////////////////////////////////
async void START(CancellationToken token)
{
for (int i = 0; i < 1; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(2000);
var t2 = Task.Run(() => START2(token));
await Task.WhenAny(new[] { t2});
}
///////////////////////////////////////////////
async void START2(CancellationToken token)
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(7000);
var t3 = Task.Run(() => MOVE(token));
await Task.WhenAny(new[] {t3});
}
//////////////////////////////////////////
async void MOVE(CancellationToken token)
{
for (int i = 0; i < 3; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
var t4 = Task.Run(() => MOVE2(token));
await Task.WhenAny(new[] {t4 });
}
在稍微简化的示例中使用 CancellationTokenSource:
CancellationTokenSource cts = new CancellationTokenSource();
async void Cancel_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => Start(token));
var t2 = Task.Run(() => Start(token));
await Task.WhenAny(new []{t1, t2});
}
catch(OperationCancelledException){
// Handle canceled
}
catch(Exception){
// Handle other exceptions
}
}
void Start(CancellationToken token)
{
for (int i = 0; i < 100; i++)
{
token.ThrowIfCancellationRequested();
// Do work
Thread.Sleep(100);
}
}
单击该按钮时,它将首先创建一个新的 cancellationTokenSource,然后在后台线程上启动两个任务,这两个任务都使用来自新创建的令牌源的令牌。当按下 cancelButton 时,令牌将设置为 canceled-state,下次每个后台线程调用 ThrowIfCancellationRequested 时,它们将抛出异常。这会将任务放入 canceled-state,等待这将抛出需要捕获的 operationCancelledException。请注意,当等待多个任务时,您可能会得到一个 aggregateException,它包装了多个异常并需要解包。