如何监视和重新启动在C#中引发异常的任务? - c#

假设我有一个实例化无限期运行的三个任务的程序。这些任务旨在并行运行。但是,可以说这些任务由于网络错误有时会引发异常。

监视任务并在必要时重新启动它最简单的技术是什么?

解决此问题的我的工作是监视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,以创建更多任务。

var taskFactories = new List<Func<Task>>();

taskFactories.Add(() => TaskMethod("1"));
taskFactories.Add(() => TaskMethod("2"));
taskFactories.Add(() => TaskMethod("3"));

var runningTasks = taskFactories.ToDictionary(factory => factory());

while (runningTasks.Count > 0)
{
    // Wait for something to happen, good or bad
    var completedTask = await Task.WhenAny(runningTasks.Keys);
    if (completedTask.IsFaulted) // Something bad happened
    {
        var factory = runningTasks[completedTask];
        var newTask = factory();
        runningTasks.Remove(completedTask);
        runningTasks.Add(newTask, factory);
    }
    else // A task just finished normally or was canceled
    {
        runningTasks.Remove(completedTask);
    }
}

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

改造正在返回一个空的响应主体 - java

我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…

每个文件合并后添加换行 - python

我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…

等待异步方法中已完成的任务 - c#

当我们调用异步方法时,我们返回一个包装器任务。public async Task ExecuteActionAsync() { // no await called } public async Task ExecuteActionAwaitAsync() { // await called on a completed await Task.Complet…

您如何在列表内部调用一个字符串位置? - python

我一直在做迷宫游戏。我首先决定制作一个迷你教程。游戏开发才刚刚开始,现在我正在尝试使其向上发展。我正在尝试更改PlayerAre变量,但是它不起作用。我试过放在列表内和列表外。maze = ["o","*","*","*","*","*",…