【问题标题】:Aborting thread + socket connection中止线程+套接字连接
【发布时间】:2014-02-25 08:26:50
【问题描述】:

我有一个(我认为非常基本的理解)关于线程和中止这些的问题:

情况是:我在一个工作线程中有一个打开的套接字连接 - 现在我正在通过thread.Abort() 中止线程。

问题是:套接字连接会发生什么?它会被关闭和处置吗?还是我必须自己处理?

附录:

在这里创建线程:

foreach (Pcd pcd in LstPcds)
        {
           Thread.Sleep(delay);
           Thread thread = new Thread(pcd.Simulate);
           _lstActiveThreads.Add(thread);
           thread.IsBackground = true;
           thread.Name = pcd.ToString();
           thread.Start();
           count++;
        }

并且应该在这里处理/中止/无论什么:

  public void DisposePcds()
  {
     try
     {
        foreach (Thread thread in _lstActiveThreads)
        {
           thread.Abort();
        }
     }
     catch (Exception exception)
     {
        MessageBox.Show(exception.ToString());
     }
  }

每个thread 都有一个打开的Socket 连接,如下所示:

// connecting (async) to the service
// blocks the thread until connection is established
ConnectionSocket = new Socket(_ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ConnectionSocket.BeginConnect(_ipEndPoint, ConnectCallback, ConnectionSocket);
_manualConnectEvent.WaitOne();

// begin receive data from the server
ReceiveDto receive = new ReceiveDto { Socket = ConnectionSocket };
ConnectionSocket.BeginReceive(receive.Buffer, 0, ReceiveDto.GetBufferSize(), 0, ReceiveCallback, receive);

加上一个 Timer 及其经过的事件,其中每个 Socket 发送一个字节数组:

byte[] request = GetRegisterRequestCommand(bank);
ConnectionSocket.Send(request, SocketFlags.None);

【问题讨论】:

  • 永远不要使用Thread.Abort()。真的。很少有使用它的正当理由。您应该使用一种机制(例如AutoResetEvent 等)来允许线程自己正常关闭。
  • 你能告诉我们你在哪里中止线程并关闭连接的部分吗?
  • 不清楚你的线程是在哪里创建的?流产时你的线程在做什么?看来您正在使用套接字的异步 API。没有充分的理由使用线程,我也没有看到。您在哪里创建线程以及它的作用是什么?
  • Thread.Abort 是不可预测的,对于像这样的 可管理 情况应避免使用。看看如何使用 TPL 执行Task Cancellation
  • 正如@SriramSakthivel 所说。你不需要线程。您可以异步执行所有单线程操作。 Please read Stephen Cleary's post on the subject.

标签: c# multithreading sockets dispose


【解决方案1】:

只需阅读有关该主题的 MSDN 文档。

首先。不,您的代码永远无法工作。 Disposables 需要在它们上显式调用.Dispose(),或者通过using(IDisposable){} 的语法糖隐式调用它们。

现在查看ThreadAbortException,您可以捕获异常(但它会被重新抛出)。所以using(由编译器转换为try{}finally{Dispose()})会起作用。

但是你没有异常处理。

【讨论】:

  • 谢谢 aron - 我知道这段代码在我们的任何宇宙中都不起作用,但实际上这不是一个“真实”场景的问题,我只是觉得缺乏理解“处理”线程及其内部操作的工作原理。
猜你喜欢
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 2011-04-28
相关资源
最近更新 更多