我需要執行這樣的任務(我無法控制該任務的源代碼)
public Task DoSomething()
有時該任務未能完成。并且此方法不會引發任何例外。在這種情況下,我想再次執行該任務,直到它完成。為此,我嘗試這樣做:
Task task;
do {
task = Task.Run(async () => await DoSomething();
await Task.Delay(300);
}
while (!task.IsCompleted);
這是正確的嗎 ?有沒有更好的方法?
uj5u.com熱心網友回復:
您應該直接使用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)。
uj5u.com熱心網友回復:
您可能想要這樣的東西:
// 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
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/313587.html
上一篇:AzureFunctions無法再創建.NETFramework運行時
下一篇:從集合中檢索隨機檔案
