[英]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.