提问人:Rumix 提问时间:8/11/2023 最后编辑:Rumix 更新时间:8/12/2023 访问量:94
异步等待 Task.WhenAll(tasks);卡住了,不会继续代码
Async await Task.WhenAll(tasks); stuck, won't continue with code
问:
现在是早上 7 点,不是那种好人。我累了,我有意大利面条代码,我只想解释一下。一般是第一次合作。代码如下:async
namespace TargetFinder
{
public class AsyncRandomIP
{
private const string BaseFolderName = "TargetLocatorData/AsyncRandomIP";
private const string FoundIPsFileName = "found_ips.txt";
private const string UnreachableIPsFileName = "unreachable_ips.txt";
public static async Task ScanAsync(Config config, int port, int amount,
Form1 form, CancellationToken cancellationToken)
{
string baseFolderPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.Desktop), BaseFolderName);
Methods.EnsureDirectoryExists(baseFolderPath);
var random = new Random();
var unreachableIPs = Methods.LoadIPsFromFile(UnreachableIPsFileName,
baseFolderPath);
var foundIPs = Methods.LoadIPsFromFile(FoundIPsFileName, baseFolderPath);
var ipQueue = new BlockingCollection<string>();
for (int i = 0; i < amount; i++)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
if (config.AllowRepeatScans)
{
ipQueue.Add(Methods.GenerateRandomIPAddress(random));
}
else
{
string ipAddress;
do
{
ipAddress = Methods.GenerateRandomIPAddress(random);
} while (unreachableIPs.Contains(ipAddress));
ipQueue.Add(ipAddress);
form.UpdateConsole("NewQueueSet: " + ipQueue);
}
}
int concurrentThreads = config.ConcurrentThreads;
var tasks = new List<Task>();
for (int i = 0; i < concurrentThreads; i++)
{
tasks.Add(Task.Run(async () =>
{
foreach (string ipAddress in ipQueue
.GetConsumingEnumerable(cancellationToken))
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
await ProcessIPAsync(config, port, unreachableIPs,
foundIPs, baseFolderPath, form, ipAddress);
}
}));
}
form.UpdateConsole(Environment.NewLine + "Waiting for finish:");
try
{
await Task.WhenAll(tasks);
Console.WriteLine("Finished");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
form.UpdateConsole(
Environment.NewLine + "IPs with requested service:");
foreach (string ip in foundIPs)
{
form.UpdateConsole(Environment.NewLine + ip);
}
}
}
private static async Task ProcessIPAsync(Config config, int port,
HashSet<string> unreachableIPs, HashSet<string> foundIPs,
string baseFolderPath, Form1 form, string ipAddress)
{
if (Methods.IsIPReachable(ipAddress))
{
using (TcpClient client = new TcpClient())
{
try
{
client.SendTimeout = config.ClientSendTimeoutMilliseconds;
await client.ConnectAsync(ipAddress, port);
form.UpdateConsole(Environment.NewLine + $"IP: {ipAddress},
Service found: true");
foundIPs.Add(ipAddress);
Methods.SaveIPsToFile(foundIPs, FoundIPsFileName,
baseFolderPath);
}
catch (SocketException)
{
Console.ForegroundColor = ConsoleColor.Red;
form.UpdateConsole(Environment.NewLine + $"IP: {ipAddress},
Service found: false");
Console.ForegroundColor = ConsoleColor.White;
foundIPs.Add(ipAddress);
Methods.SaveIPsToFile(foundIPs, FoundIPsFileName,
baseFolderPath);
}
}
}
else
{
form.UpdateConsole(
Environment.NewLine + $"IP: {ipAddress}, Not reachable");
unreachableIPs.Add(ipAddress);
Methods.SaveIPsToFile(unreachableIPs, UnreachableIPsFileName,
baseFolderPath);
}
}
}
}
我无法弄清楚任务在哪里冻结和未完成,控制台没有多大用处,ChatGPT 也没有多大用处。如果有人可以检查一下并让我知道,那么我写这篇文章的方式就会受到批评,而不是我最自豪的项目。如果有人能帮忙,我将不胜感激。
其他 form1 代码。
namespace TargetFinder
{
public partial class Form1 : Form
{
private SynchronizationContext uiContext;
private CancellationTokenSource cancelTokenSource;
public Form1()
{
InitializeComponent();
uiContext = SynchronizationContext.Current;
cancelTokenSource = new CancellationTokenSource();
}
private void label10_Click(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
thread_tb.Text = Convert.ToString(thread_trackbar.Value);
if (print_res_bt.Checked)
{
format_bt.Enabled = true;
}
else
{
format_bt.Enabled = false;
}
}
private void Button2_Click(object sender, EventArgs e)
{
thread_tb.Text = "4";
thread_trackbar.Value = 4;
amount_tb.Text = "50";
timeout_tb.Text = "3000";
print_res_bt.Checked = true;
format_bt.SelectedItem = ".TXT";
}
private void configurationToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void print_res_bt_CheckedChanged(object sender, EventArgs e)
{
}
private void directoryToolStripMenuItem_Click(object sender, EventArgs e)
{
directory_set.ShowDialog();
}
private void scan_button_Click(object sender, EventArgs e)
{
try
{
int port = Convert.ToInt32(port_tb.Text);
int amount = Convert.ToInt32(amount_tb.Text);
cancelTokenSource = new CancellationTokenSource(); // Reset CancellationTokenSource
Info.Main(port, amount, this, cancelTokenSource.Token);
}
catch (OperationCanceledException)
{
console.AppendText(Environment.NewLine + "Scan cancelled.");
}
}
public void UpdateConsole(string text)
{
uiContext.Post(new SendOrPostCallback(delegate
{
console.AppendText(text);
}), null);
}
private void cancel_button_Click(object sender, EventArgs e)
{
cancelTokenSource.Cancel();
}
private void button1_Click(object sender, EventArgs e)
{
console.Text = "";
}
private void set_btn_Click(object sender, EventArgs e)
{
int clientSendTimeoutMilliseconds = Convert.ToInt32(timeout_tb.Text);
int concurrentThreads = Convert.ToInt32(thread_tb.Text);
bool allowRepeatScans = repeat_scan_bt.Checked;
ConfigManager.SetConfig(clientSendTimeoutMilliseconds, concurrentThreads, allowRepeatScans);
MessageBox.Show("Configuration updated.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
答: 暂无答案
评论
neither is chatgpt
为什么你认为统计生成的文本会有所帮助?WhenAll
不会冻结,只有在所有任务完成时才会完成。使用 时,枚举不会完成,直到发布者使用 完成枚举。异步代码不一定是意大利面条代码。将发布者和订阅者分隔到单独的类中,并使用适当的类。异步发布/订阅集合是 Channel<T>,而不是 .任务不是线程,而是承诺。 通过负责创建工作线程并将项目传递给他们,消除了问题中的大量代码GetConsumingEnumerable
CompleteAdding
BlockingCollection
Parallel.ForEachAsync
ScanAsync
ipQueue.CompleteAdding();
Parallel.ForEachAsync
BlockingQueue
await Parallel.ForEachAsync(list,async (item,ct)=>await someMethod(item,ct))