在 C# 中获取 "Empty Queue" 异常

Getting an "Empty Queue" exception in C#

我正在尝试使用代理同时 运行 多个请求。我希望代理一次发起一个请求,这就是为什么我有一个 gethandlerindexed 函数

此外,错误发生在最后一次调用 gethandlerindexed 时,这里最大 = 2,所以我有 2 个代理,2 个用户代理,但它不起作用。有问题的错误是:空队列

我不明白这个错误是从哪里来的。

int indext = 0;

private async Task DoDownload(IEnumerable<ClearanceHandler> handlers, SemaphoreSlim sem, string url)
{
    await Task.Delay(100);

    try
    {
        await sem.WaitAsync();
        indext++;
        var client = new HttpClient(gethandlerindexed(indext, handlers)); // error in question appear here
        string link_image = null;

        using (HttpResponseMessage response = await client.GetAsync(url))
        {
            using (HttpContent content = response.Content)
            {
                link_image = await content.ReadAsStringAsync();
                richTextBox1.TextInvoke(link_image);
            }
        }
    }
    finally
    {
        sem.Release();
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    ServicePointManager.DefaultConnectionLimit = 20;
}

ClearanceHandler gethandlerindexed(int nb, IEnumerable<ClearanceHandler> handlers)
{
    return (handlers.ElementAt(nb % handlers.Count()));
}

Queue<string> getdatafromfile(string path)
{
    Queue<string> q = new Queue<string>();

    var proxies = File.ReadAllLines(path);

    for (int i = 0; i < 2; i++)
        q.Enqueue(proxies[i]);

    return (q);
}

private async void button1_Click(object sender, EventArgs e)
{
    var proxies = getdatafromfile(PATH + "\proxy\proxy.txt");
    var useragents = getdatafromfile(PATH + "\proxy\user-agents.txt");

    // MessageBox.Show(proxies.Count() + " / " + useragents.Count());

    var max = proxies.Count();
    var handlers = Enumerable.Range(0, max).Select(_ => new ClearanceHandler(proxies.Dequeue()) { UserAgent = useragents.Dequeue(), MaxTimeout = 6000 });
    var semaphore = new SemaphoreSlim(max, max);

    await Task.Run(async () =>
        {
            var downloads = Enumerable.Range(0, max).Select((_ => "http://google.com")).ToArray();
            var tasks = downloads.Select(dl => DoDownload(handlers, semaphore, dl));
            await Task.WhenAll(tasks);
        });
}

Error in question

你的问题是你不断地耗尽你的队列。

您开始创建两个队列:

var proxies = getdatafromfile(PATH + "\proxy\proxy.txt");
var useragents = getdatafromfile(PATH + "\proxy\user-agents.txt");

您这样创建 IEnumerable<ClearanceHandler> handlers

var handlers = Enumerable.Range(0, max).Select(_ => new ClearanceHandler(proxies.Dequeue()) { UserAgent = useragents.Dequeue(), MaxTimeout = 6000 });

你将其传递给 DoDownload 并调用它:

var client = new HttpClient(gethandlerindexed(indext, handlers));

gethandlerindexed 中调用 handlers.ElementAt(nb % handlers.Count())

现在,因为 handlers 是一个 IEnumerable<ClearanceHandler>,您每次都在重新运行枚举。所以它每次运行时都会调用 proxies.Dequeue()useragents.Dequeue()

以下是适合您的方法:

var handlers =
    Enumerable
        .Range(0, max)
        .Select(_ => new ClearanceHandler(proxies.Dequeue()) { UserAgent = useragents.Dequeue(), MaxTimeout = 6000 })
        .ToArray();

注意 .ToArray()。这会强制执行一次可枚举。只要两个队列具有相同数量的元素,它就可以正常工作。