2009-11-24 21 views
1

我正在用C#编写一个应用程序,并且我创建了多个BackgroundWorker线程来从网页中获取信息。尽管他们是BackgroundWorkers,但我的GUI表单变得没有反应。在Main中处理Web请求?

当我调试时,我暂停时,程序无响应,我可以看到我在主线程,我暂停了网页抓取方法。这个方法只能从新线程调用,所以我不知道为什么我会在主线程中。

这是否有意义?我可以做些什么来确保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() 
} 

当创建工作对象,它使用“我”就知道它是什么的线程数。它将使用它来获取网站地址列表(从主窗体,控制器和每个WorkObjects共享的更大地址列表中获取信息 - 每个线程将处理更小的地址列表)。当它遍历列表时,它会调用“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; 
} 
+2

你能发表一些代码吗?确定启动线程的代码和请求 – mfeingold 2009-11-24 20:32:13

+0

。希望这是足够的/不太多的信息。 – Matt 2009-11-24 21:36:17

回答

0

你应该在你的BackgroundWorker的DoWork的事件中执行所有的网络工作,是吗?

一些限制的代码可以帮助我们理解发生了什么。

+0

好的,编辑后添加了一些代码。希望这是足够的信息 – Matt 2009-11-24 21:38:57

0

在类似的情况下,我发现我通过创建自己的线程(不使用BackgroundWorker并且没有ThreadPool)并限制活动连接的数量可以更好地进行控制。将IP地址写入Queue,然后选择每个IP地址,然后将其传递给助手类,在该类中您可以在新线程上调用其DoSomething方法。通过在启动线程时递增计数器并在线程完成时递减计数来进行限制。您可以使用助手类中的回调例程来指示您的UI线程更新界面或指示线程已完成。

使用您的用户界面来改变油门限制并观察任务管理器以查看对内存和CPU使用情况的影响。您可以在app.config中添加maxconnection设置以获得更多同时连接。

+0

最初,我创建了自己的线程,但这导致UI挂起,所以我决定尝试BackgroundWorkers。仍然有同样的问题。 CPU使用率和内存使用率一般都很低 - 除了当我告诉它一次创建一堆线程时,但一旦它们启动就会停止运行。 – Matt 2009-11-25 18:28:00