假设我有一个程序实例化三个无限期运行的任务。这些任务旨在并行运行。但是,假设这些任务偶尔会由于网络错误而引发异常。
监视任务并在必要时重新启动它的最简单技术是什么?
我解决此问题的方法是监视 Task.Status 数据,并在任务发生故障时简单地调用 Task.Start() 方法。
但是,此代码不起作用,因为任务异常会导致整个应用程序崩溃。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var my_task = Program.MainAsync();
my_task.Wait();
}
public static async Task MainAsync()
{
var task_1 = Program.TaskMethod("1");
var task_2 = Program.TaskMethod("2");
var task_3 = Program.TaskMethod("3");
// loop indefinitely restarting task if necessary
while(true)
{
if (task_1.Status == TaskStatus.Faulted)
task_1.Start();
if (task_2.Status == TaskStatus.Faulted)
task_2.Start();
if (task_3.Status == TaskStatus.Faulted)
task_3.Start();
await Task.Delay(1000);
}
}
public static async Task TaskMethod(string task_id)
{
Console.WriteLine("Starting Task {0}", task_id);
while(true)
{
await Task.Delay(5000);
Console.WriteLine("Hello from task {0}", task_id);
int i = 0;
int b = 32 / i;
}
}
}
}
最佳答案
自 Task
无法重启,可以考虑使用任务工厂Func<Task>
每次 Task
时都可以一次又一次地调用它失败,创建更多任务。
List<Func<Task>> taskFactories = new();
taskFactories.Add(() => TaskMethod("1"));
taskFactories.Add(() => TaskMethod("2"));
taskFactories.Add(() => TaskMethod("3"));
Task[] enhancedTasks = taskFactories.Select(async factory =>
{
while (true)
{
try
{
Task task = factory();
await task;
break; // On success stop
}
catch (OperationCanceledException) { throw; } // On cancellation stop
catch { await Task.Delay(1000); continue; } // On error restart after a delay
}
}).ToArray();
await Task.WhenAll(enhancedTasks);
每个工厂预计将增强 Task
其中包括失败时重新启动功能。 Select
LINQ 运算符用于进行投影。
注意:原始答案包含 Task.WhenAny
-in-a-loop 反模式,可以在 second revision 中找到这个答案。
关于c# - 如何在 C# 中监视和重新启动引发异常的任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59431924/