2012-08-17 71 views
1

我有一些一些代碼如下:使用Abort()停止多線程時凍結GUI?

List<WebRequestUri> lwebrequest = new List<WebRequestUri>(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Start_Click(object sender, EventArgs e) 
    { 
     Thread thread = new Thread(new ParameterizedThreadStart((object context) => 
      { 
       DoWork(); 
      })); 
     thread.IsBackground = true; 
     thread.Start();    
    } 

    void DoWork() 
    { 
     lwebrequest = new List<WebRequestUri>(); 
     for (int i = 0; i < 100; i++) 
     { 
      WebRequestUri wp = new WebRequestUri(); 
      wp.Start(); 
      lwebrequest.Add(wp); 
     } 
    } 

    private void Stop_Click(object sender, EventArgs e) 
    {     
     for (int i = 0; i < lwebrequest.Count; i++) 
     {    
      lwebrequest[i].Abort(); 
     } 
    } 

工人階級:

class WebRequestUri 
{ 
    Thread thread = null; 
    WebRequest webRequest = null; 
    WebResponse webResponse = null; 
    StreamReader sr = null; 

    public void Start() 
    { 
     thread = new Thread(new ParameterizedThreadStart((object context) => 
      { 
       SendRequest(); 
      })); 
     thread.IsBackground = true; 
     thread.Start(); 
    } 

    public void Abort() 
    {    
     if (webResponse != null) webResponse.Close(); 
     if (webRequest != null) webRequest.Abort(); 
     if (thread != null) thread.Abort();    
    } 

    public void SendRequest() 
    { 
     webRequest = WebRequest.Create("http://google.com"); 

     webRequest.ContentType = "application/x-www-form-urlencoded"; 
     webRequest.Method = "GET";   
     try 
     { 
      webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest); 
     } 
     catch (WebException) 
     { 
     } 
    } 

    private void GetResponseCallback(IAsyncResult asynchronousResult) 
    { 
     try 
     { 
      webRequest = (HttpWebRequest)asynchronousResult.AsyncState; 
      webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult); 
      sr = new StreamReader(webResponse.GetResponseStream()); 
      string response = sr.ReadToEnd(); 
      Console.Write(response); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 
} 

我得到的一個問題,當我嘗試單擊停止按鈕。我看到我的表單被阻止。我不確定我的停止功能是對還是錯。你能給我一些建議嗎?謝謝

回答

0

其他可能的原因已被其他人提出。 然而更重要的是Thread.Abort的實際使用。

它被認爲是a very bad thing to do,你不會相信問題的數量和微妙的錯誤。

好消息是,你通常不需要它,異步任務的完成可以並且應該由應用程序本身來處理。考慮你的用例,例如:

你想通過調用abort完成什麼?你想中止請求嗎?你不能,因爲它已經在進行中。它將到達目的地並被處理,無論對方是否有人在等待它。 但是,如果您試圖避免不必要的計算 - 您可以完全控制。您可以在名爲「abortRequested」的類中保留一個布爾成員,並且Abort方法將其設置爲「true」。您想中止的方法需要不時檢查該成員,以決定是否應該繼續執行。

如果需要,我們可以進一步分析您的用例。

編輯: 這將是這個樣子:

bool stopped = false; // can make this thread safe if you want. 

// Assuming you have a computation in a loop. 
compouteAsynch(){ 

    for(var workItme in workItems){ 
    if(!stopped){ 
     dostuff(workItem) 
    } 
    } 
} 

void stop(){ 
    stopped = true; // work will not stop immediately. Only in the next iteration. 
} 

,你喜歡,你可以控制「停止」抽樣的粒度。但是,您必須意識到無法在任何地方對其進行抽樣。例如,當線程針對數據庫執行查詢時,您無法檢查它。儘管如此,這應該足夠好。

+0

如果我使用bool變量並將其設置爲「true」時,我想停止線程,我認爲它會非常緩慢。因爲請求需要在bool變量=「true」之後執行。所以它不會立即停止。對於我的問題,Vitaliy有你的想法嗎?謝謝。 – 2012-08-20 01:34:28

+0

@HùngLêXuân,的確,它不會馬上停止。但是你可以在一定程度上控制抽樣的粒度。請參閱我的編輯。 – Vitaliy 2012-08-20 05:00:48

0

它看起來像你試圖同步中止Web請求,可能已經開始。這些請求的處理可能正在進行中,所以我懷疑此次中止呼叫可能是掛起的。如果你只是想調用中止,我會考慮在另一個工作線程上這樣做,這樣GUI至少可以返回。

+0

但我呼叫放棄線程之前中止web請求。所以我試圖刪除Web請求並將其替換爲Thread.Sleep(10000),但我的GUI線程被阻止。我不知道爲什麼?感謝您的快速回答。 – 2012-08-17 09:38:45

相關問題