[英]How to make sure a task is completed in c#
我需要执行这样的任务(我无法控制该任务的源代码)
public Task DoSomething()
有时该任务未能完成。 并且此方法不会引发任何异常。 在这种情况下,我想再次执行该任务,直到它完成。 为此,我尝试这样做:
Task task;
do {
task = Task.Run(async () => await DoSomething();
await Task.Delay(300);
}
while (!task.IsCompleted);
这是正确的吗 ? 有没有更好的方法?
您应该直接使用await
调用异步方法。
如果出现错误,应该抛出异常。
你的代码应该变成这样。
bool repeat = false;
do {
try
{
await DoSomething();
repeat = false;
}
catch
{
repeat = true;
}
if (repeat)
await Task.Delay(300);
}
while (repeat); // better with some kind of timeout or attempts counter...
此外, IsCompleted
还包括Faulted
和Cancelled
。 如果您想使用您的方法,您需要使用新属性IsCompletedSuccessfully
或排除IsFault
和IsCancelled
(如果您使用旧的 .NET fwk)。
您可能想要这样的东西:
// Trying to complete task again and again...
// you may want to give some number of attempt to complete, say
// for (int attempt = 1; attempt <= 3; ++i) {
while (true) {
// Let task 300 ms to completet before it'll be canceled
using (CancellationTokenSource cts = new CancellationTokenSource(300)) {
try {
await DoSomething(cts.Token);
// Task Succeeded, break the loop
break;
}
catch (TaskCanceledException) {
// Task Cancelled, keep on looping
;
}
}
}
请注意,您应该在DoSomething
获得一些支持:
async Task DoSomething(CancellationToken token)
代替
async Task DoSomething()
因为我们应该知道如何取消它。 如果你没有
async Task DoSomething(CancellationToken token)
或类似的签名,(使用CancellationToken
),残酷的事实是你不能取消。 您可以尝试等待(如果任务未完成,则忘记该任务):
// Since we are going to forget running tasks, let's
// restrict number of attempts
for (int attempt = 1; attempt <= 3; ++attempt) {
Task task = DoSomething();
if (await Task.WhenAny(task, Task.Delay(300)) == task) {
// task has been completed before timeout
break;
}
// we forget task (alas, we can't cancel it) and try again
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.