2011-10-16 72 views
2

正如标题所暗示的。 是的,我知道这是horribad使用.abort(),但听我把话说完强制关闭'流氓'线程如果中止()不起作用

我使用的是2个线程,主线程(我的应用程序)和插座听线程(熟悉的声音的人?) 而不是使用异步的.AcceptAsync()调用(tbh,主要原因是我没有看太多),我有线程挂在socket.Accept(); Ofcourse,当我调用thread.Abort()时,线程不会关闭,因为它仍然在等待连接,一旦它通过Accept()它会中止就好。

代码:

void listenserver() 
    { 
     while (run) 
     { 
      fConsole.WriteLine("Waiting for connections.."); 
      connectedsock = mainsock.Accept(); 
      connected = true; 
      fConsole.WriteLine("Got connection from: " + connectedsock.RemoteEndPoint); 

... 和其他地方:

private void button_start_Click(object sender, EventArgs e) 
    { 
     if (!run) 
     { //code ommitted. 
     } 
     else 
     { 
      run = false; 
      listenthread.Join(3000); 
      if (listenthread.IsAlive) 
      { 
       fConsole.WriteLine("Force-closing rogue listen thread"); 
       listenthread.Abort(); 
      } 
      button_start.Text = "Start"; 
      groupBox_settings.Enabled = true; 
     } 

是有保证的线程将结束,不是要的东西,在一个单独的应用程序的整个事情的任何方式那么结束呢? 请注意,我确实将thread.IsBackground设置为true(正如其他论坛主题中所建议的那样),但它没有任何区别。

+1

如果您知道'BeginAccept'和'EndAccept'将解决您的问题,为什么您继续寻求一种不涉及这些方法的解决方案? –

+0

因为我只想要1个连接同时打开。我知道使用async会大量扩展我的代码,所以我认为我会尽可能简单地做到这一点,并像这样做。猜猜这不是一种可能性,那么我只会使用acceptasync。 – Alex

回答

1

由于您已经在使用线程,因此您可能只需使用BeginAccept即可。异步代码并不需要复杂的代码,因为你可以使用lambda表达式是这样的:

var socket = new Socket(...); 

socket.BeginAccept(result => 
{ 
    if (this.abort) 
    { 
     // We should probably use a signal, but either way, this is where we abort. 
     return; 
    } 

    socket.EndAccept(result); 
    // Do your sockety stuff 
}, null); 

即使对于AsyncCallback一个单独的方法定义,代码并不复杂。

通过执行异步IO,您的CPU时间也更加高效,因为在调用BeginAcceptEndAccept之间,该线程可以重新用于其他处理。既然你在等待连接时没有将它用于任何有意义的事情,那么举行一个线程就显得毫无意义而且效率低下。

+1

似乎是合理的,但你必须保持线程循环,否则程序将退出(因为在这种情况下它是一个控制台项目)。或者BeginAccept()是否阻塞了线程?没有不可解释的那就是..--无论如何,我将这个标记为一个好的答案,除了我已经找到了一个杀死套接字的方法,它会抛出一个中断的异常,如果你关闭另一个线程中的套接字,如果你处理您可以优雅地关闭线程。 – Alex

+1

你必须保持GUI线程活着,是的。 'BeginAccept'将立即返回。 –