中止线程或仅让计算机清理它

本文关键字:计算机 线程 | 更新日期: 2023-09-27 17:56:40

我有以下代码,如果线程在 2 秒内未完成,我想中止它。您可以从第一个代码中看到,我在 while 循环中创建了一个新的 myThread evertyime,并且不会中止它。好吧,我不希望它像这样,但是如果我将myThread带到循环之外并像第二个代码一样使用abort()函数。中止时会出现错误。

while (true)
        {
            try
            {
                m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//reset up socket
                myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));
                myThread.Start();
                if (!myThread.Join(2000))
                {
                    throw new SocketException(SocketError.AccessDenied);
                }
            }
            catch (Exception ex)
            {
                m_socket.Close();
            }
        }
    }
     private static void socket_connect()
    {
        m_socket.Connect(remoteEndPoint);//Connect to remote device  
    }

我一开始尝试以下代码,但它给出了线程中止异常。

 myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));   
  while (true)
        { try
            {
                m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,     ProtocolType.Tcp);//reset up socket
                myThread.Start();
                if (!myThread.Join(2000))
                {
                    myThread.Abort();
                    throw new SocketException(SocketError.AccessDenied);
                }
            }
            catch (Exception ex)
            {
                m_socket.Close();
            }
        }
    }
    private static void socket_connect()
    {
        m_socket.Connect(remoteEndPoint);//Connect to remote device  
    }

我知道 abort() 不是一个好主意,所以我转而让线程留下来让 C#(.Net?我不知道谁实际上这样做)处理垃圾收集。谁能说出这是否是一个好主意,因为该程序将在没有大量内存来容纳线程束的板上运行。有人可以告诉我垃圾收集是如何在 C# 中完成的吗?例如线程。
另一件需要提及的事情是我没有 Task 类或 socket.beginconnect() 方法,我想这是因为我正在构建一个将在小板上运行的程序,而不是 PC。该板是一个netduido plus,我正在netduino plus平台上构建我的项目。

中止线程或仅让计算机清理它

我有以下代码,如果线程在 2 秒内未完成,我想中止线程。

阅读代码,看起来您实际上想尝试在两秒钟内将套接字连接到资源。如果超过两秒,您要继续前进。

我主要是在这个答案中重现代码,我相信这大约是你应该做的来实现你的目标,而不是启动一个线程并中止它:

Socket socket = new Socket(AddressFamily.InterNetwork,
                           SocketType.Stream,
                           ProtocolType.Tcp);
// Connect using a timeout (2 seconds)
IAsyncResult result = socket.BeginConnect( sIP, iPort, null, null );
bool success = result.AsyncWaitHandle.WaitOne( 2000, true );
if ( !success )
{
            // NOTE, MUST CLOSE THE SOCKET
            socket.Close();
            throw new ApplicationException("Failed to connect server.");
}
// Success
//... 

[编辑:取消制表符/空格时大量复制粘贴失败]

哦,请使用Task库,处理这些情况更容易:

(LINQPad-Friendly blob)

void Main()
{
    var canceller = new CancellationTokenSource();
    var task = Task.Factory.StartNew(() => DoStuff(canceller.Token), canceller.Token);        
    if(!task.Wait(2000, canceller.Token))
    {
        canceller.Cancel();
        task.Wait(2);
    }
    sw.Elapsed.Dump();
}
private Stopwatch sw;
private void DoStuff(CancellationToken token)
{
    try
    {
        sw = Stopwatch.StartNew();
        while(!token.IsCancellationRequested)
        {       
        }
    }
    // no catch - rethrown exceptions must be checked on Task
    finally
    {
        sw.Stop();
    }
}

或者,您可以使用一些"退出标志"条件 - 线程启动器和线程运行程序都可以看到/更改的布尔值,并在while条件下使用它。