我正在創建一個 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 個“有自己的生活”并在其中運行異步的任務。我的問題是任務相互等待。回圈將逐漸創建 10 個任務(因為Task.Delay(600))=> Bot 將被創建并啟動bot.Connect();
假設它總是需要相同的時間來完成Connect()。
從邏輯上講,第一個任務應該比第二個任務快 600 毫秒。問題是程式一直等到所有Connect()完成。然后它逐漸開始,然后完成它們,但第一個任務直到串列中的最后一個機器人完成后SendTokens()才會開始。SayHi()SendTokens()
為什么會這樣,我不明白。我試過設定
ThreadPool.SetMaxThreads(500, 500);
但這對我沒有任何幫助。
這是實時除錯輸出的示例,LoadOptions()逐漸啟動多次,但第一個LoadOptions()應該已經完成??,下一個方法應該已經啟動,但它正在等待所有LoadOptions結束。我不在代碼中使用Task.WaitAll()。

誰能幫我解決這個問題并告訴我出了什么問題?我想在未來學習和了解。非常感謝,祝您有愉快的一天。
uj5u.com熱心網友回復:
據我了解,您的回圈會啟動 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; }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/496632.html
上一篇:多執行緒初學者查詢(C )
