gpt4 book ai didi

c# - Parallel.For WebRequests - 第一个请求什么都不做

转载 作者:行者123 更新时间:2023-11-30 22:09:11 26 4
gpt4 key购买 nike

我有一个帐户列表。我想使用网站上的所有帐户登录。我想使用 Parallel.ForEach 来处理所有帐户。这是我的代码的样子:

Parallel.ForEach(Accounts,
acc =>
{
acc.WebProxy = null;
acc.Channel = "pelvicpaladin__";
Debug.WriteLine("Connecting to {0}.", new object[] { acc.Username });
acc.ConnectToIrc().Wait();
});

除一个问题外,一切正常:帐户列表中的第一个帐户不起作用。内部我必须使用多个请求(它不仅仅是登录)。第一个请求什么都不做。如果我破坏了调试器,就没有可用的源代码。

我有大约 12 个帐户。我试图从列表中删除第一个帐户。但问题仍然是一样的(现在新的第一个(旧的第二个)帐户失败了)。

现在非常奇怪的一点是:如果我不使用 Parallel.For,一切正常。

foreach (var acc in Accounts)
{
acc.WebProxy = null;
Debug.WriteLine("Connecting to {0}.", new object[] { acc.Username });
await acc.ConnectToIrc();
}

同样:除了列表中的第一个帐户外,一切正常。它始终是第一个(它不取决于列表包含多少帐户或哪个帐户是第一个帐户)。

有人知道吗?

编辑:这就是我创建 WebRequests 的方式:

private async Task<string> GetResponseContent(HttpWebRequest request)
{
if (request == null)
throw new ArgumentNullException("request");

using (var response = await request.GetResponseAsync())
{
return await GetResponseContent((HttpWebResponse)response);
}
}

private async Task<string> GetResponseContent(HttpWebResponse response)
{
if (response == null)
throw new ArgumentNullException("response");

using (var responseStream = response.GetResponseStream())
{
return await new StreamReader(responseStream).ReadToEndAsync();
}
}

private HttpWebRequest GetRequest(string url)
{
if (String.IsNullOrWhiteSpace(url))
throw new ArgumentNullException("url");

try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.CookieContainer = _cookieContainer;
request.Referer = url;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 GTB6 (.NET CLR 3.5.30729)";
if (_webProxy != null)
request.Proxy = WebProxy.WebProxy;

request.KeepAlive = true;
request.Timeout = 30000;

return request;
}
catch (Exception ex)
{
ErrorLogger.Log(String.Format("Could not create Request on {0}.", url), ex);
return null;
}
}

最佳答案

您遇到了典型的等待死锁情况。问题是您对 ConnectToIrc 的调用正在使用 await 并捕获同步上下文。他们试图将延续编码到主线程。问题是您的主线程正忙于阻止对 Parallel.ForEach 的调用。它不允许任何这些延续运行。主线程正在等待延续继续,延续正在等待主线程可以自由运行。死锁。

这就是(原因之一)为什么你不应该同步等待异步操作。

相反,只需启动所有异步操作并使用 WhenAll 等待它们全部完成。无需创建新线程,或使用线程池等。

var tasks = new List<Task>();
foreach (var acc in Accounts)
{
acc.WebProxy = null;
Debug.WriteLine("Connecting to {0}.", new object[] { acc.Username });
tasks.Add(acc.ConnectToIrc());
}
await Task.WhenAll(tasks);

这与您的第二个示例不同,它将并行执行所有异步操作,同时仍然异步等待。

关于c# - Parallel.For WebRequests - 第一个请求什么都不做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21703919/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com