我想在 C# 中做这样的事情
public static async Task<int> Method1()
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong) Exit task here.
count += 1;
}
});
return count;
}
如果出现问题我想终止任务。 我该怎么做?
您可以考虑取消令牌和任务运行 在此示例中,我们将
CancellationToken
传递给该方法,这允许我们在出现问题时取消任务。然后我们将 cancellationToken
传递给 Task.Run
方法,这允许在请求时取消任务。 -(任务运行不在示例中)
public static async Task<int> Method1(CancellationToken cancellationToken)
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
{
// Cancel the task
cancellationToken.ThrowIfCancellationRequested();
}
count += 1;
}
}, cancellationToken);
return count;
}
进一步阅读的链接
CancellationToken:https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken?view=net-6.0
Task.Run:https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run?view=net-6.0
只需抛出一个未捕获的异常,这将结束任务并使其进入
IsFaulted
状态。
https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1?view=net-8.0
if (something wrong) throw new InvalidOperationException("failed to reticulate splines");
最好的解决方案是使用 CancellationToken。
public static async Task<int> Test(CancellationToken cancellationToken)
{
var result= 0;
for (var i = 0; i < 100; i++)
{
cancellationToken.ThrowIfCancellationRequested();
// your code
result++;
}
return result;
}
现在使用它:
var cancellationToken= new CancellationTokenSource();
var testTask=Test(cancellationToken.Token);
如果需要取消任务,可以使用:
cancellationToken.Cancel();
如果需要测试方法的结果,可以使用:
awaite testTask;
async
/await
的重点是您可以编写与同步代码非常相似的异步代码。
所以,让我们扭转局面:
如果出现问题我想终止任务。我该怎么做?
在同步世界中,这将是:
如果出现问题,我想终止循环。我该怎么做?
原来的同步代码看起来是这样的:
public static int Method1()
{
int count = 0;
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
Exit task here.
count += 1;
}
return count;
}
同步世界中的答案是“抛出异常”(首选)或“提前返回”(不常用),例如:
public static int Method1()
{
int count = 0;
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
throw new InvalidOperationException("something wrong");
count += 1;
}
return count;
}
或者,不太常见:
public static int Method1()
{
int count = 0;
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
return count;
count += 1;
}
return count;
}
同样,在异步世界中,答案是“抛出异常”(首选)或“提前返回”(不常用):
public static int Method1()
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
throw new InvalidOperationException("something wrong");
count += 1;
}
});
return count;
}
或者,不太常见:
public static int Method1()
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
// Do Stuff
if (something wrong)
return;
count += 1;
}
});
return count;
}
尝试使用
break;
你将以这种方式退出 for 循环。return 0;
如果你想退出整个函数也可以工作。
另外,你也可以把函数放在一个try-catch语句中,万一发生崩溃,崩溃会被捕获到catch()部分。
如果你想从外部完成任务,你可以使用
CancellationToken
,如果你因为错误而想从函数内部结束任务,使用try catch
.
public static async Task<int> Method1(CancellationToken ct)
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
try{
// Do Stuff
count += 1;
//rom outside the function
if(ct.IsCancellationRequested)
break;
//cancellationToken.ThrowIfCancellationRequested(); If you just want to terminate the task
}
catch(Exception e)
{
break;
}
}
});
return count;
}
运行任务:
CancellationTokenSource _cts = new CancellationTokenSource();
Task.Run(() => Method1(_cts.Token));
终止任务: 如果你想从函数外完成任务:
if (something wrong)
_cts.Cancel();