0

I'm working on a backup manager for some Quest (critical infrastructure monitoring devices) when running the Code it seems to be running my tasks as its adding them to a task list before calling .WhenAll. then when calling .WhenAll i get null ref exceptions and aggregate Exceptions. I'm using a telnet nuget, you can assume the telnet works as it works on its own and when running this synchronously

I'm new to Async/Await in c#. Ive tried getting rid of the telnet portion and just run the HTTP and vice versa. Ive removed the async Method(runBackupAsync) and run direct to the async class (BackupSingleBoxAsync) no change

(BackupSingleBoxAsync)

    private Quest QuestBox = new Quest();

    public BackupSingleBoxAsync(Quest q)
    {
        this.QuestBox.IP = q.IP;
        this.QuestBox.User = q.User;
        this.QuestBox.Password = q.Password;
        this.QuestBox.Type = q.Type;

    }

    public async Task<Quest> StartAsync()
    {
        Quest tempQuest = new Quest();
        while (QuestBox.User != null && QuestBox.Password != null)
        {
            if (QuestBox.Type.ToLower().Contains("mini"))
            {
                HttpDownload getRes = new HttpDownload(QuestBox);
                tempQuest = await getRes.Start();
            }
            else
            {
                Telnet getRes = new Telnet(QuestBox);
                tempQuest = await getRes.Start();
            }

        }
        this.QuestBox.Results = tempQuest.Results;

        return QuestBox;
    }

(Backup Controller)

        GetConfigs config = new GetConfigs(QuestMasterList);
        List<Quest> questAterDownload = config.GetAll().Result;

(GET CONFIGS)

    public List<Quest> QuestMasterList = new List<Quest>();

    public GetConfigs(List<Quest> list)
    {
        this.QuestMasterList.AddRange(list);
    }

    public async Task<List<Quest>> GetAll()
    {
        List<Task<Quest>> task_list = new List<Task<Quest>>();
        foreach (var quest in QuestMasterList)
        {
            task_list.Add(runBackupAsync(quest));
        }

        await Task.WhenAll(task_list);

        List<Quest> tempQuests = new List<Quest>();

        foreach (var tsk_rslt in task_list)
        {
            tempQuests.Add(tsk_rslt.Result);
        }

        return tempQuests;
    }

    private async Task<Quest> runBackupAsync(Quest quest)
    {
        BackupSingleBoxAsync backup = new BackupSingleBoxAsync(quest);
        Quest res = backup.StartAsync().Result;
        return res;
    }

(Quest)

    public string IP;
    public string User;
    public string Password;
    public string Type;
    public bool Success;
    public bool Diff;
    public List<string> Results = new List<string>();

I Expect it to return a list of quest box type but instead it gives null ref exceptions and aggregate exceptions

  • 2
    Try using `var foo = await task;` instead of `var foo = task.Result;` in all possible places (except when you do `await Task.WhenAll`, of course). This will ensure that all the tasks will finish before accessing the results. – Guilherme Apr 26 '19 at 17:28
  • that's what they originally were i changed them to .Result trying to troubleshoot – Brett Jackson Apr 26 '19 at 17:40
  • They are all changed back now, still same result. – Brett Jackson Apr 26 '19 at 17:46
  • I'f you're getting exceptions, they'll tell you what and where the problem is. – Paulo Morgado Apr 26 '19 at 19:17
  • The main issue I'm having is its running tasks before i tell it to. rogue task starting – Brett Jackson Apr 26 '19 at 20:05
  • 2
    "when calling .WhenAll i get null ref exceptions" - are any tasks in the list `null`? "The main issue I'm having is its running tasks before i tell it to." - with async, tasks start running immediately. When an async method returns a task, that task is already running. If you want to delay execution, use `Func` instead of `Task`. – Stephen Cleary Apr 26 '19 at 20:39
  • 1
    You may need to know that when awaiting a `Task.WhenAll`, not all exceptions that have aggregated are thrown. Only one of the exceptions is thrown. You can read an interesting discussion about this design decision [here](https://stackoverflow.com/questions/18314961/i-want-await-to-throw-aggregateexception-not-just-the-first-exception), along with at least two good workarounds. In your case I would suggest to add exception handling inside the method `runBackupAsync`, and in case of exception print it in the console. It is much easier this way than dealing down the road with AggregateExceptions. – Theodor Zoulias Apr 26 '19 at 21:18

0 Answers0