Как ждать задачи и назначать значения переменным - PullRequest
0 голосов
/ 13 сентября 2018

Я пытался понять это немного сейчас, но я не могу обернуться вокруг этого.У меня есть следующая асинхронная задача, которая вызывает другие асинхронные задачи из моего объекта ClientFunctions с именем "c".

public async Task RunAsync(Dictionary<int, Robots> botList)
{
    this.botList = botList;
    Task[] tasks = new Task[botList.Count]; //5 tasks for each bot, 5 bots total in a list

    for (int i = 0; i < botList.Count; i++)
    {
        tasks[i] = botList[i].c.StartClient();
        await tasks[i];

        tasks[i] = botList[i].c.setConnection();
    }
    await Task.WhenAll(tasks);
    Form1.Log("All done");
}

Я жду после StartClient(), потому что он записывает данные в общий файл, а setConnection() читаетданные из этого файла.Я делаю это для всех 5 ботов.

Функция StartClient() возвращает Process, и я хочу сохранить этот процесс в классе каждого бота в переменной с именем " proc ".

Как бы я мог сохранить результат, все еще имея возможность использовать массив задач для ожидания завершения всех 5?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Вот одна из возможных реализаций, при условии, что вы хотите StartClient для всех ботов последовательно, а затем вызвать setConnection и await их всех для завершения.

public async Task RunAsync(Dictionary<int, Robots> botList)
{
    this.botList = botList;
    var tasks = new List<Task>();
    foreach(var botKvp in botList)
    {
        var bot = botKvp.Value;
        bot.proc = await bot.c.StartClient();
        tasks.Add(bot.c.setConnection());
    }
    await Task.WhenAll(tasks);
    Form1.Log("All done");            
}

Task выпускается в двух вариантах: Task и Task<T>. У вас есть массив Task, который не определяет возвращаемое значение. Если вы хотите вернуть значение, вам нужно await a Task<T>. Например, если setConnection() должен вернуть bool, тогда его подпись должна объявить, что public Task<bool> setConnection(...)

Task[] tasks = new Task<Process>[botList.Count]

должно быть

Task<Process>[] tasks = new Task<Process>[botList.Count]

Это работает

bot.proc = await bot.c.StartClient();

Becuase StartClient() возвращает Task<Process>, а await ожидает этой задачи и назначает процесс proc. В качестве встречного примера это не удастся:

Task procTask = bot.c.StartClient();
bot.proc = await procTask
0 голосов
/ 13 сентября 2018

Когда вы ожидаете задания, вы получаете результат, поэтому:

public async Task RunAsync(Dictionary<int, Robots> botList)
{
    this.botList = botList;
    Task[] tasks = new Task[botList.Count]; //5 tasks for each bot, 5 bots total in a list

    for (int i = 0; i < botList.Count; i++)
    {
        tasks[i] = botList[i].c.StartClient();
        botList[i].proc = await tasks[i];

        tasks[i] = botList[i].c.setConnection();
    }
    await Task.WhenAll(tasks);
    Form1.Log("All done");
}

Если бы это был метод setConnection(), который вернул элемент, результат await Task.WhenAll(tasks) содержал бы коллекцию элементов.

...