2009-11-24 79 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