2012-08-17 43 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

相关问题