[英]Tasks wait for each other to complete
I'm creating a Selenium bot as a WPF application.我正在创建一个 Selenium 机器人作为 WPF 应用程序。 I'm using Tasks to create bots and then tasks to perform things on bot.我正在使用任务来创建机器人,然后使用任务在机器人上执行任务。
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);
}
I have array of accounts and I loop through them.我有一系列帐户,我遍历它们。
Let's say accounts.Length = 10
=> I want to create 10 tasks that will 'have their own life' and run async inside of them.假设accounts.Length = 10
=> 我想创建 10 个“拥有自己的生活”并在其中运行异步的任务。 My problem is that Tasks wait for each other.我的问题是任务相互等待。 Loop will create 10 tasks gradually (because of Task.Delay(600)
) => Bot will be created and start bot.Connect();
Loop 将逐渐创建 10 个任务(因为Task.Delay(600)
)=> Bot 将被创建并启动bot.Connect();
Lets say it takes always same amount of time to complete Connect()
.可以说完成Connect()
总是需要相同的时间。
Logically first Task should be completed 600ms faster than second Task.从逻辑上讲,第一个任务应该比第二个任务快 600 毫秒。 Problem is that program waits until all Connect()
are completed.问题是程序一直等到所有Connect()
都完成。 Then it starts gradually all SendTokens()
then complete them, but first task won't start SayHi()
until SendTokens()
of last bot in list is completed.然后它逐渐启动所有SendTokens()
然后完成它们,但第一个任务不会启动SayHi()
直到列表中最后一个机器人的SendTokens()
完成。
Why is that happening, I don't understand that.为什么会这样,我不明白。 I tried setting我试过设置
ThreadPool.SetMaxThreads(500, 500);
but that does nothing for me.但这对我没有任何帮助。
Here is example of live debug output, starts LoadOptions()
gradually many times, but first LoadOptions()
should be already completed and next method should be already started but it is waiting for all LoadOptions
to end.这是实时调试输出的示例,逐步启动LoadOptions()
多次,但第一个LoadOptions()
应该已经完成,下一个方法应该已经启动,但它正在等待所有LoadOptions
结束。 I don't use in code Task.WaitAll()
.我不在代码Task.WaitAll()
中使用。
Can anyone help me fix this issue and tell me what was wrong?谁能帮我解决这个问题并告诉我出了什么问题? I want to learn and know in future.我想在未来学习和了解。 Thank you very much and have a nice day.非常感谢,祝您有愉快的一天。
As I understand it, your loop launches N bots and starts them on a "Life of their own" .据我了解,您的循环会启动 N 个机器人并以“自己的生活”启动它们。 The loop provides a spacing of 600 ms between Bot
launches.该循环在Bot
启动之间提供 600 毫秒的间隔。 The Bot
class contains various async
tasks, and for any given Bot
there is an example start sequence of Connect
, SendTokens
, and SayHi
where each of these three methods must complete before the next one starts. Bot
类包含各种async
任务,对于任何给定的Bot
,都有一个Connect
、 SendTokens
和SayHi
的示例启动序列,其中这三个方法中的每一个都必须在下一个方法开始之前完成。
But apart from that, each bot should be taking care of its own internal tasks concurrently while other bots are taking care of theirs.但除此之外,每个机器人应该同时处理自己的内部任务,而其他机器人则在处理它们的内部任务。 A typical concurrent timeline might look like this:典型的并发时间线可能如下所示:
Here's one approach you could try to achieve this outcome.这是您可以尝试实现此结果的一种方法。 If the Bot
class comes from a library where it can't be modified you can still make an async
Extension method for it instead.如果Bot
类来自无法修改的库,您仍然可以为其创建async
扩展方法。 (I'll show it that way just in case. Otherwise just make it a normal method of the Bot
class.) Note that the return type is void
; (以防万一,我会以这种方式显示。否则,只需将其Bot
类的普通方法。)请注意,返回类型是void
; the Bot
has a life of its own per your post!根据您的帖子, Bot
有自己的生命! We don't wait for it to live its life.我们不会等待它过上它的生活。 HOWEVER it has internal business where one async
activity must run to completion before the next one starts, and this extension method accounts for that.然而,它有内部业务,其中一个async
活动必须在下一个活动开始之前运行完成,而这种扩展方法说明了这一点。
static class Extensions
{
public static async void PostInitAsyncRequest(this BlackBoxBot bot)
{
await bot.Connect();
await bot.SendTokens();
await bot.SayHi();
}
}
All your WPF
application needs to do is call the launchAllBots
method which waits 600 ms between launches.您的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);
}
}
SIMULATION In order to mock this startup timeline, the following fake Bot
class was used:模拟为了模拟这个启动时间线,使用了以下假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.