[英]Tasks wait for each other to complete
我正在创建一个 Selenium 机器人作为 WPF 应用程序。 我正在使用任务来创建机器人,然后使用任务在机器人上执行任务。
foreach (string account in accounts)
{
count++;
_ = Task.Run(async () =>
{
Bot bot = new Bot();
//here is long code for what should bot do ASYNC
//example
await bot.Connect();
await bot.SendTokens();
await bot.SayHi();
});
await Task.Delay(600);
}
我有一系列帐户,我遍历它们。
假设accounts.Length = 10
=> 我想创建 10 个“拥有自己的生活”并在其中运行异步的任务。 我的问题是任务相互等待。 Loop 将逐渐创建 10 个任务(因为Task.Delay(600)
)=> Bot 将被创建并启动bot.Connect();
可以说完成Connect()
总是需要相同的时间。
从逻辑上讲,第一个任务应该比第二个任务快 600 毫秒。 问题是程序一直等到所有Connect()
都完成。 然后它逐渐启动所有SendTokens()
然后完成它们,但第一个任务不会启动SayHi()
直到列表中最后一个机器人的SendTokens()
完成。
为什么会这样,我不明白。 我试过设置
ThreadPool.SetMaxThreads(500, 500);
但这对我没有任何帮助。
这是实时调试输出的示例,逐步启动LoadOptions()
多次,但第一个LoadOptions()
应该已经完成,下一个方法应该已经启动,但它正在等待所有LoadOptions
结束。 我不在代码Task.WaitAll()
中使用。
谁能帮我解决这个问题并告诉我出了什么问题? 我想在未来学习和了解。 非常感谢,祝您有愉快的一天。
据我了解,您的循环会启动 N 个机器人并以“自己的生活”启动它们。 该循环在Bot
启动之间提供 600 毫秒的间隔。 Bot
类包含各种async
任务,对于任何给定的Bot
,都有一个Connect
、 SendTokens
和SayHi
的示例启动序列,其中这三个方法中的每一个都必须在下一个方法开始之前完成。
但除此之外,每个机器人应该同时处理自己的内部任务,而其他机器人则在处理它们的内部任务。 典型的并发时间线可能如下所示:
这是您可以尝试实现此结果的一种方法。 如果Bot
类来自无法修改的库,您仍然可以为其创建async
扩展方法。 (以防万一,我会以这种方式显示。否则,只需将其Bot
类的普通方法。)请注意,返回类型是void
; 根据您的帖子, Bot
有自己的生命! 我们不会等待它过上它的生活。 然而,它有内部业务,其中一个async
活动必须在下一个活动开始之前运行完成,而这种扩展方法说明了这一点。
static class Extensions
{
public static async void PostInitAsyncRequest(this BlackBoxBot bot)
{
await bot.Connect();
await bot.SendTokens();
await bot.SayHi();
}
}
您的WPF
应用程序需要做的就是调用launchAllBots
方法,该方法在两次启动之间等待 600 毫秒。
async void launchAllBots()
{
foreach (string account in new string[]
{"Jessie", "Ross", "Kensho", "Ernest", "Amy", "Andrew", "Baxter", "Jibo", "Buddy"})
{
// Has its own life so DO NOT AWAIT
var bot = new BlackBoxBot();
bot.Account = account;
bot.PostInitAsyncRequest();
// But DO await the delay to space out Bot launches
await Task.Delay(600);
}
}
模拟为了模拟这个启动时间线,使用了以下假Bot
类:
// A crude mock of the 'Bot' class with internal async methods.
class BlackBoxBot
{
public async Task Connect()
{
Console.WriteLine($"{DateTime.Now.ToString("ss:fff")} {Account}: {nameof(Connect)}");
await Task.Delay(_rando.Next(400, 800));
}
public async Task SendTokens()
{
Console.WriteLine($"{DateTime.Now.ToString("ss:fff")} {Account}: {nameof(SendTokens)}");
await Task.Delay(_rando.Next(400, 800));
}
public async Task SayHi()
{
Console.WriteLine($"{DateTime.Now.ToString("ss:fff")} {Account}: {nameof(SayHi)}");
await Task.Delay(_rando.Next(400, 800));
}
static Random _rando = new Random();
public string Account { get; internal set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.