我有一个使用ThreadPool-threads下载文件的下载工作者。在对这些文件进行增强后,将一些Selenium测试应用于下载的文件,我经常遇到文件下载的TimeOut异常和运行Selenium测试的延迟。更确切地说:
现在这里是下载代码:
HttpWebRequest request = null;
WebResponse response = null;
Stream stream = null;
StreamReader sr = null;
try
{
request = (HttpWebRequest) WebRequest.Create(uri);
request.ServicePoint.ConnectionLimit = MAX_CONNECTIONS_PER_HOST;
response = request.GetResponse();
stream = response.GetResponseStream();
// Read the stream...
}
finally
{
if (request != null) request.Abort();
if (response != null) response.Close();
if (stream != null)
{
stream.Close();
stream.Dispose();
}
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}
这就是Selenium之后在同一个线程中使用的方式:
lock(SeleniumLock)
{
selenium.Open(url);
// Run some Selenium commands, but no selenium.stop()
}
其中selenium
是在类的静态构造函数中初始化的静态变量(通过selenium.start()
)。
我假设我遇到了CLR连接限制,所以我在初始化过程中添加了这些行:
ThreadPool.GetMaxThreads (out maxWorkerThreads, out maxCompletionPortThreads);
HttpUtility.MAX_CONNECTIONS_PER_HOST = maxWorkerThreads;
System.Net.ServicePointManager.DefaultConnectionLimit = maxWorkerThreads + 1;
+ 1
用于连接到SeleniumRC,因为我猜测Selenium客户端代码也使用了HttpWebRequest。看起来我仍然遇到某种死锁 - 虽然等待Selenium锁的线程没有任何资源。
有关如何使其发挥作用的任何想法?
答案 0 :(得分:1)
在深入研究之后,我认为该问题与连接有关,而与ThreadPool和HttpWebRequest无关:在下载程序开始遇到超时的时间点,ThreadPool.GetAvailableThreads()
返回0或-1可用工人线程。我小心翼翼地选择同步使用HttpWebRequest以确保不会发生这种情况。据推测,Selenium客户端驱动程序使用异步方法,产生这种“线程死锁”。
我不确定解决此问题的最佳方法是什么,但ThreadPool.QueueUserWorkItem()
的替代方法替代了该程序至少可用:
protected void QueueWorkItem(WaitCallback callBack, object state)
{
// Wait for available thread (as Selenium's async I/O is mixed with ThreadPool and yields deadlocks)
int b, c;
do
{
ThreadPool.GetAvailableThreads(out b, out c);
if (b < 10) Thread.Sleep(250);
} while (b < 10);
// Queue the work item
if (ThreadPool.QueueUserWorkItem(callBack, state)) Interlocked.Increment(ref WorkItemCount);
}