C#-如何既等待任务又给变量赋值

时间:2018-09-13 20:05:10

标签: c# asynchronous async-await task

我已经尝试了好一会儿,但似乎无法绕开它。我有以下异步任务,该任务从名为“ c”的ClientFunctions对象中调用其他异步任务。

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,我想将该Process存储在每个bot的类中的变量“ proc ”中。

在仍然能够使用任务数组等待所有5个完成的同时,如何存储结果?

谢谢。

2 个答案:

答案 0 :(得分:0)

等待任务时,您会得到结果,所以:

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)的结果将保存项目的集合。

答案 1 :(得分:0)

这里是一种可能的实现方式,假设您想依次对所有漫游器进行StartClient,然后调用setConnectionawait将它们全部完成。

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有两个变体:TaskTask<T>。您有一个Task数组,该数组未定义返回值。如果要返回值,则需要awaitTask<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();

因为StartClient()返回Task<Process>,并且await等待该任务并将进程分配给proc。作为反例,这将失败:

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