我正在用C#编写应用程序,我正在创建多个BackgroundWorker线程来从网页中获取信息。尽管他们是BackgroundWorkers,但我的GUI表格却没有反应。
当我调试时,我暂停程序没有响应时,我可以看到我在主线程中,我暂停了网页提取方法。但是这个方法只能从新线程调用,所以我无法弄清楚为什么我会在主线程中存在。
这有什么意义吗?我该怎么做才能确保只在各自的线程中处理Web请求?
编辑:一些代码和解释
我正在处理大量地址。每个线程将处理一个或多个地址。我可以选择我想要创建多少个线程(我保持谦虚:))
//in “Controller” class
public void process()
{
for (int i = 1; i <= addressList.Count && i<= numthreads; i++)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += doWork;
bw.RunWorkerAsync((object)i);
}
}
public void doWork(object sender, DoWorkEventArgs e)
{
//create an object that has the web fetching method, call it WorkObject
//WorkObject keeps a reference to Controller.
//When it is done getting information, it will send it to Controller to print
//generate a smaller list of addresses to work on, using e.Argument (should be 'i' from the above 'for' loop)
WorkObject.workingMethod()
}
创建WorkObject时,它使用“i”来知道它是什么线程号。它将使用它来获取Web地址列表以从中获取信息(来自主表单,Controller和每个WorkObject共享的更大地址列表 - 每个线程将处理较小的地址列表)。当它遍历列表时,它将调用“getWebInfo”方法。
//in “WorkObject” class
public static WebRequest request;
public void workingMethod()
{
//iterate over the small list of addresses. For each one,
getWebInfo(address)
//process the info a bit...then
myController.print()
//note that this isn’t a simple “for” loop, it involves event handlers and threading
//Timers to make sure one is done before going on to the next
}
public string getWebInfo (string address)
{
request = WebRequest.Create(address);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string content = reader.ReadToEnd();
return content;
}
答案 0 :(得分:0)
您应该在BackgroundWorker的DoWork活动中执行所有网络工作,是吗?
一些剪切的代码可以帮助我们了解正在发生的事情。
答案 1 :(得分:0)
在类似的情况下,我发现通过创建自己的线程(没有BackgroundWorker和没有ThreadPool)并限制活动连接的数量,我可以更好地控制。将IP地址写入队列,然后选择每个IP地址,将其传递给一个辅助类,在新的线程上调用它的DoSomething方法。通过在启动线程时递增计数器并在线程完成时递减计数器来限制。您可以使用helper类中的回调例程来指示您的UI线程更新接口或指示线程已完成。
使用您的UI来改变限制,并观察任务管理器以查看对内存和CPU使用情况的影响。您可以在app.config中添加maxconnection设置以获得更多同时连接。
答案 2 :(得分:0)
我无法弄清楚为什么后台工作人员会导致挂起,但我没有使用同步HTTP请求,而是使用本指南切换到异步:
http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/
清除所有悬挂。感谢您的回复。