中止一个线程或者让它由计算机清理?

时间:2013-01-30 23:31:52

标签: c# multithreading garbage-collection thread-safety netduino

我有以下代码,如果在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  
    }

我最初尝试使用以下代码,但是它提供了threadabortexceptions。

 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 个答案:

答案 0 :(得分:1)

  

我有以下代码,如果在2秒内未完成,我想中止一个帖子。

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

我主要是在this answer中复制代码,我相信这大致是你应该为实现目标所做的,而不是启动线程并中止它:

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
//... 

答案 1 :(得分:-1)

[编辑:大量的copypasta在解开/间隔时失败]

哦,请使用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();
    }
}

或者,您可以使用一些“退出标志”条件 - 您的线程启动器和您的线程转换器都可以看到/更改的bool,并在while条件下使用它。