【问题标题】:FORCE closing 'rogue' threads if abort() doesn't work如果 abort() 不起作用,则强制关闭“流氓”线程
【发布时间】:2011-10-16 22:03:05
【问题描述】:

正如标题所暗示的那样。 是的,我知道使用 .abort() 很糟糕,但请听我说

我正在使用 2 个线程,主线程(我的应用程序)和一个套接字监听线程(任何人都熟悉吗?) 我没有使用异步 .AcceptAsync() 调用(tbh,主要原因是我没有过多研究它们),而是让线程挂在 socket.Accept(); 当然,当我调用 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(如其他论坛帖子中所建议的那样),但它没有任何区别。

【问题讨论】:

  • 如果您知道BeginAcceptEndAccept 可以解决您的问题,为什么还要继续寻求不涉及这些方法的解决方案?
  • 因为我只希望同时打开 1 个连接。而且我知道使用 async 会大大扩展我的代码,所以我想我会尽可能简单地做到这一点。我猜这是不可能的,那我就用acceptasync吧。

标签: c# multithreading sockets abort forceclose


【解决方案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 之间,线程可以重用于其他处理。由于您在等待连接时没有将其用于任何有目的的事情,因此保持线程毫无意义且效率低下。

【讨论】:

  • 看起来很合理,但无论如何你必须保持线程循环,否则程序会退出(因为在这种情况下它是一个控制台项目)。还是 BeginAccept() 也会阻塞线程?没有不可中断的就是..--无论如何,我会将此标记为一个很好的答案,除了我已经找到了一种杀死套接字的方法,如果你在另一个线程中关闭套接字,它会抛出一个中断的异常,如果你句柄,您可以优雅地关闭线程。
  • 您必须保持 GUI 线程处于活动状态,是的。 BeginAccept 将立即返回。
猜你喜欢
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 2021-08-19
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多