3

我有以下代码,如果线程在 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平台上构建我的项目。

4

2 回答 2

1

我有以下代码,如果线程在 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
//... 
于 2013-01-31T03:54:00.473 回答
-1

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

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

(LINQPad 友好的 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条件下使用它。

于 2013-01-31T02:29:57.793 回答